#include "GameMode.h"
#include "GameActor.h"
#include "GameActor3d.h"
#include "GameWorld.h"
#include "Globals.h"
#include "GuildInfo.h"
#include "Insult.h" // CInsultFilter
#include "Item.h"
#include "ModeMgr.h"
#include "MsgStrings.h"
#include "Npc.h"
#include "Packet.h"
#include "Picker.h"
#include "Player.h"
#include "RagEffect2.h" // CWeather
#include "Struct.h"
#include "TipOfTheDay.h" // CTipOfTheDay
#include "WinMain.h" // CheckSystemMessage()
#include "Base/ResMgr.h"
#include "Device/Connection.h"
#include "Device/Sound.h"
#include "Device/Timer.h"
#include "Framework/Locale.h"
#include "Resource/Attr.h"
#include "Window/UIGage.h"
#include "Window/UIItemWnd.h"
#include "Window/UINameBalloonText.h"
#include <math.h> // floor()
const float infinity = 999999.0;


hook_val<unsigned long> CGameMode::m_lastLockOnPcGid(SAKEXE, "CGameMode::m_lastLockOnPcGid"); // = ?
hook_val<unsigned long> CGameMode::m_dwOldAutoFollowTime(SAKEXE, "CGameMode::m_dwOldAutoFollowTime"); // = ?
hook_val<unsigned long> CGameMode::m_dwOldDisappearTime(SAKEXE, "CGameMode::m_dwOldDisappearTime"); // = ?
unsigned long& nextCacheUnloadTime = *(unsigned long*)DetourFindFunction(SAKEXE, "nextCacheUnloadTime"); // = ?
int& motionNum = *(int*)DetourFindFunction(SAKEXE, "motionNum"); // = ?


CGameMode::CGameMode(void) // line 93-97
{
	m_world = NULL;
	m_view = NULL;
	m_mousePointer = NULL;
}


CGameMode::~CGameMode(void) // autogenerated
{
}


hook_method<void (CGameMode::*)(const char* modeName)> CGameMode::_OnInit(SAKEXE, "CGameMode::OnInit");
void CGameMode::OnInit(const char* modeName) // line 100-194
{
	return (this->*_OnInit)(modeName);

	m_world = new CWorld();
	m_world->m_curMode = this;

	m_view = new CView();
	m_view->CView::SetWorld(m_world);

	strcpy(m_rswName, modeName);

	mystd::string bmpname;
	bmpname = "유저인터페이스\\map\\";
	bmpname += modeName;
	bmpname.resize(bmpname.size() - 4);
	bmpname += ".bmp";
	strcpy(m_minimapBmpName, bmpname.c_str());

	g_renderer->CRenderer::Clear(1);
	g_session.CSession::SetWeight(0); //inlined
	g_session.CSession::SetMaxWeight(0); //inlined
	g_windowMgr.UIWindowMgr::SetWallpaper(NULL);
	g_windowMgr.UIWindowMgr::RemoveAllWindowsExceptChatWnd();
	g_windowMgr.UIWindowMgr::HideChatWnd();
	g_windowMgr.UIWindowMgr::MakeWindow(WID_LOADINGWND);
	g_windowMgr.UIWindowMgr::SendMsg(UIM_LOADINGPERCENT, 0, 0, 0);
	g_windowMgr.UIWindowMgr::Render();
	if( g_renderer->CRenderer::DrawScene() )
		g_renderer->CRenderer::Flip(true);
	m_view->OnEnterFrame();
	m_world->CWorld::OnEnterFrame();
	m_isCheckGndAlpha = 0;
	this->CGameMode::SetCamera();
	m_mousePointer = new CMousePointer();
	m_world->m_gameObjectList.push_back(m_mousePointer);
	m_streamFileName = g_session.CSession::GetMp3Name(m_rswName);

	if( !g_session.m_bgmIsPaused )
		PlayStream(m_streamFileName.c_str());

	SetRoomEffect(0);
	g_session.CSession::IsEnableObjLightMap(m_rswName);
	g_Weather.CWeather::SetObjLight(true);

	if( strncmp(m_rswName, "comodo.rsw", 11) == 0 && g_serviceType == 2 )
		g_Weather.CWeather::LaunchPokJuk();

	if( strncmp(m_rswName, "yuno.rsw", 9) == 0 )
		g_renderer->CRenderer::SetBackgroundColor(0xFF99CCFF);
	else
	if( strncmp(m_rswName, "valkyrie.rsw", 13) == 0 )
		g_renderer->CRenderer::SetBackgroundColor(0xFF99CCFF);
	else
	if( strncmp(m_rswName, "gonryun.rsw", 12) == 0 )
		g_renderer->CRenderer::SetBackgroundColor(0xFF6699CC);
	else
	if( strncmp(m_rswName, "gon_dun02.rsw", 14) == 0 )
		g_renderer->CRenderer::SetBackgroundColor(0xFF6699CC);
	else
		g_renderer->CRenderer::SetBackgroundColor(0x00000000);

	this->CGameMode::MakeFog(g_session.m_fogOn);
	this->CGameMode::Initialize();

	mystd::list<mystd::string>& exlist = g_session.CSession::GetNumExNameList();
	for( mystd::list<mystd::string>::iterator it = exlist.begin(); it != exlist.end(); ++it )
		this->CGameMode::ProcessTalkType(TT_REQ_WHISPER_PC_EX, (int)&*it);

	ResetTimer();
	m_isCtrlLock = 0;
	m_showTimeStartTick = 0;
	m_autoSaveChatCnt = 0;
	m_recordChatNum = 0;
	m_strikeNum = 0;
	memset(m_doritime, 0, sizeof(m_doritime));

	if( g_session.m_isSaveChat && g_session.CSession::IsMasterAid(7) )
	{
		char msg[256];
		sprintf(msg, "Now Auto chat Save System is ENABLED.");
		g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)msg, 0x00FFFF, 0);
	}
}


hook_method<int (CGameMode::*)(void)> CGameMode::_OnRun(SAKEXE, "CGameMode::OnRun");
int CGameMode::OnRun(void) // line 320-333
{
	return (this->*_OnRun)();

	while( m_loopCond )
	{
		if( g_sysQuit )
			break;

		if( !g_windowMgr.UIWindowMgr::IsModalStatus() )
		{
			if( m_nextSubMode != -1 )
			{
				m_subMode = m_nextSubMode;
				m_subModeCnt = 0;
				m_nextSubMode = -1;
				this->OnChangeState(m_subMode);
			}
		}

		this->OnUpdate();
	}

	this->CMode::RunFadeOut(0);
	return 1;
}


hook_method<void (CGameMode::*)(void)> CGameMode::_OnExit(SAKEXE, "CGameMode::OnExit");
void CGameMode::OnExit(void) // line 337-369
{
	return (this->*_OnExit)();

	EndDigitalSound();

	if( m_world != NULL )
	{
		m_world->CWorld::OnExitFrame();
		delete m_world;
	}

	if( m_view != NULL )
	{
		m_view->OnExitFrame();
		delete m_view;
	}

	g_actorPickNode.CActorPickNode::DeleteSubNode();
	g_resMgr().CResMgr::UnloadResByExt("rsm");
	g_resMgr().CResMgr::UnloadResByExt("rsw");
	g_resMgr().CResMgr::UnloadResByExt("gat");
	g_resMgr().CResMgr::UnloadRarelyUsedRes();
	g_texMgr.CTexMgr::UnloadRarelyUsedTexture();
	g_renderer->CRenderer::DestroyAllRPList();
	g_renderer->CRenderer::ReleaseCacheSurfaces();
	g_windowMgr.UIWindowMgr::WriteShorcutItemInfoToReg();
	g_windowMgr.UIWindowMgr::WriteSkillUseLevelInfoToReg();
	g_windowMgr.UIWindowMgr::WriteFriendNameListToRegistry();
	g_session.CSession::WriteExListToRegistry();
	this->CGameMode::WriteNameBalloonPosToReg(); //inlined
	this->CGameMode::SaveCamera(); //inlined
	this->CGameMode::CloseChatFile(); //inlined
}


hook_method<void (CGameMode::*)(void)> CGameMode::_OnUpdate(SAKEXE, "CGameMode::OnUpdate");
void CGameMode::OnUpdate(void) // line 209-317
{
	return (this->*_OnUpdate)();

	CheckSystemMessage();
	this->CGameMode::PollNetworkStatus();

	if( m_loopCond )
	{
		this->CGameMode::ProcessInput();
		this->CGameMode::ProcessAutoFollow();
		this->CGameMode::ProcessPlayWave();

		if( g_isSkipFrame > 0 )
		{
			if( timeGetTime() > m_syncRequestTime + 12000 )
			{
				m_receiveSyneRequestTime = 0;
				m_syncRequestTime = timeGetTime();

				PACKET_CZ_REQUEST_TIME packet;
				packet.PacketType = HEADER_CZ_REQUEST_TIME;
				packet.clientTime = timeGetTime();
				g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);

				if( g_pingLog )
				{
					g_pingLogList.push_back(timeGetTime());
					if( g_pingLogStart == 0 )
						g_pingLogStart = g_pingLogList.front();
				}
			}

			this->CGameMode::ProcessAssignAID();

			if( timeGetTime() > nextCacheUnloadTime )
			{
				nextCacheUnloadTime = timeGetTime() + 15000;
				g_renderer->CRenderer::UnloadRarelyUsedCaches();
			}
		}

		int skip = GetSkipFrameCount();
		g_isSkipFrame = ( skip != 0 );

		for( int i = 0; i < skip; ++i )
		{
			m_world->CWorld::ProcessActors();
			m_world->m_ground->C3dGround::UpdateWater();
			m_view->OnCalcViewInfo();
		}

		if( skip == 0 )
		{
			m_world->CWorld::ProcessActors();
			m_view->OnCalcViewInfo();
		}
	}

	if( g_activatedNow != 0 )
	{
		g_activatedNow = 0;
		if( g_3dDevice.C3dDevice::IsFullscreen() )
		{
			g_3dDevice.C3dDevice::RestoreSurfaces();
			g_windowMgr.UIWindowMgr::InvalidateAll();
		}
	}

	g_Weather.CWeather::Process();

	if( !g_isAppActive && g_3dDevice.C3dDevice::IsFullscreen() )
		return;

	if( SkipSceneRendering() != 0 )
	{
		g_renderer->CRenderer::ClearBackground();
		g_actorPickNode.CActorPickNode::DeleteSubNode();
		m_view->OnRender();
		this->CGameMode::DrawMiniMap();
		this->CGameMode::DrawIllustImage();
		g_windowMgr.UIWindowMgr::Render();

		if( m_world->CWorld::IsPKZone() )
		{
			this->CGameMode::DrawPKRanking();

			int rank = m_world->m_player->CPc::GetPKRank();
			int total = m_world->m_player->CPc::GetPKTotal();

			if( total > 0 && rank > 0 && total > 1 && rank == 1 )
			{
				this->CGameMode::DrawTime(g_session.m_killTimeStartTick, 1);

				if( g_session.m_killTimeStartTick != 0 && timeGetTime() - g_session.m_killTimeStartTick < 3000 )
				{
					CActRes* act = (CActRes*)g_resMgr().CResMgr::Get("이팩트\\TimeAttack.act");
					CSprRes* spr = (CSprRes*)g_resMgr().CResMgr::Get("이팩트\\TimeAttack.spr");

					int motId = motionNum / 3;
					if( motId < act->CActRes::GetMotionCount(0) )
					{
						this->CMode::DrawSprite(g_renderer->CRenderer::GetWidth() / 2 - spr->m_sprites[0].front()->height / 2, 120, act, spr, 0, motId, 1.0, 0.0, 0xFFFFFFFF);
						++motionNum;
					}
				}
			}
		}

		if( g_session.m_isShowTime )
			this->CGameMode::DrawTime(g_session.m_showDigitTick, g_session.m_showType);
		this->CGameMode::DrawDragImage();
		this->CMode::DrawMouseCursor();
		this->CGameMode::DrawUseSkillLevelNumber();
		this->CMode::ProcessFadeIn();

		if( g_renderer->CRenderer::DrawScene() )
			g_renderer->CRenderer::Flip(true);
	}

	this->CMode::ScreenShot();
}


hook_method<int (CGameMode::*)(int messageId, int val1, int val2, int val3)> CGameMode::_SendMsg(SAKEXE, "CGameMode::SendMsg");
int CGameMode::SendMsg(int messageId, int val1, int val2, int val3) // line 27-3024 (GameMode2.cpp)
{
	return (this->*_SendMsg)(messageId, val1, val2, val3);

	switch( messageId )
	{
//	case 0: //MM_COMMAND
//		//default
//	break;
	case 1: //MM_SOCKETERROR
		m_noMove = 1;
		m_noMoveStartTick = timeGetTime();
		g_connection.CConnection::Disconnect();
		if( g_windowMgr.UIWindowMgr::ErrorMsg(MsgStr(MSI_UNABLE_TO_CONNECT_SERVER), 0, 1, 1, 0) != 178 )
			this->SendMsg(MM_QUIT_TO_IDENTRY, 0, 0, 0);
	break;
//	case 2: //MM_QUIT
//		//default
//	break;
//	case 3: //MM_RECV
//		//default (unused)
//	break;
	case 4: //MM_SHOWMOUSEPOINTER
	{
		float cx = (float)val1;
		float cy = (float)val2;
		int color = (int)val3;

		this->CGameMode::ShowMousePointer(cx, cy, color);
	}
	break;
	case 5: //MM_HIDEMOUSEPOINTER
	{
		int time = (int)val1;

		this->CGameMode::HideMousePointer(time);
	}
	break;
	case 6: //MM_CHATMSG
	{
		if( strlen(g_windowMgr.UIWindowMgr::GetChatMsg()) == 0 || g_session.CSession::IsEFST_Berserk() == 1 )
			break;

		char chat2[246+1];
		strcpy(chat2, g_windowMgr.UIWindowMgr::GetChatMsg());

		if( g_insultFilter.CInsultFilter::IsBadSentence(chat2) )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_NO_SEND_BECAUSE_INSULT), 0x0000FF, 0);
			g_windowMgr.UIWindowMgr::ClearChatMsg();
			break;
		}

		if( m_lastChat == chat2 )
			++m_sameChatRepeatCnt;
		else
			m_sameChatRepeatCnt = 0;
		if( m_sameChatRepeatCnt >= 2 )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_NO_SAME_SENTANCE), 0x0000FF, 0);
			g_windowMgr.UIWindowMgr::ClearChatMsg();
			break;
		}

		m_lastChat = chat2;

		char altMsg1[246+1];
		char altMsg2[246+1];
		char altMsg3[246+1];
		char altMsg4[246+1];
		if( strlen(chat2) > 6 )
		{
			memcpy(altMsg1, chat2, sizeof(altMsg1));
			size_t altMsg1len = strlen(altMsg1);
			if( altMsg1len + 3 < 247 )
			{
				altMsg1[altMsg1len + 3] = altMsg1[altMsg1len + 1];
				altMsg1[altMsg1len + 2] = altMsg1[altMsg1len + 0];
				altMsg1[altMsg1len + 1] = altMsg1[altMsg1len - 1];
				altMsg1[altMsg1len + 0] = altMsg1[altMsg1len - 2];
			}

			memcpy(altMsg2, chat2, sizeof(altMsg2));
			size_t altMsg2len = strlen(altMsg2);
			if( altMsg2len + 1 < sizeof(altMsg2) )
			{
				altMsg2[altMsg2len + 1] = altMsg2[altMsg2len - 0];
				altMsg2[altMsg2len + 0] = altMsg2[altMsg2len - 1];
			}

			memcpy(altMsg3, chat2, sizeof(altMsg3));
			size_t altMsg3len = strlen(altMsg3);
			if( altMsg3len + 1 < sizeof(altMsg3) )
			{
				altMsg3[altMsg3len - 1] = altMsg3[altMsg3len + 0];
				altMsg3[altMsg3len - 0] = altMsg3[altMsg3len + 1];
			}

			memcpy(altMsg4, chat2, sizeof(altMsg4));
			size_t altMsg4len = strlen(altMsg4);
			if( altMsg4len + 1 < sizeof(altMsg4) )
			{
				altMsg4[altMsg4len - 2] = altMsg4[altMsg4len + 0];
				altMsg4[altMsg4len - 1] = altMsg4[altMsg4len + 1];
			}
		}

		if( m_recordChatNum == 10 )
		{// make room at the end by shifting everything to the left
			for( int i = 0; i < 10; ++i )
			{
				m_recordChat[i] = m_recordChat[i+1];
				m_recordChatTime[i] = m_recordChatTime[i+1];
			}
		}

		m_recordChat[m_recordChatNum] = chat2;
		m_recordChatTime[m_recordChatNum] = timeGetTime();
		
		++m_recordChatNum;
		if( m_recordChatNum > 10 )
			m_recordChatNum = 10;

		int nRepeats = 0;
		for( int i = 0; i <= m_recordChatNum; ++i )
		{
			if( i == 10 )
			{
				if( timeGetTime() - m_recordChatTime[0] < 10000 && timeGetTime() != m_recordChatTime[0] )
				{
					this->CGameMode::ChatDori();
					m_strikeNum = 0;
					break;
				}

				if( timeGetTime() - m_recordChatTime[0] < 30000 && timeGetTime() != m_recordChatTime[0] )
				{
					for( int j = 0; i < m_recordChatNum && m_recordChat[j].length() < 20; ++i )
					{
						if( j == m_recordChatNum - 1 )
						{
							g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)"TOO FAST CHATTING!", 0x6E96FF, 0);
							this->CGameMode::ChatDori();
							m_strikeNum = 0;
							break;
						}
					}
				}

				if( g_session.CSession::GetJob() == JT_SUPERNOVICE || g_session.CSession::GetJob() == JT_SUPERNOVICE_B )
				{
					char snPhrase1[256];
					sprintf(snPhrase1, MsgStr(MSI_SUPERNOVICE1)); //FIXME: uncontrolled format string vulnerability

					char snPhrase2[256];
					sprintf(snPhrase2, "%s %s%s", MsgStr(MSI_SUPERNOVICE2), g_session.CSession::GetCharName(), MsgStr(MSI_SUPERNOVICE3));

					char snPhrase3[256];
					sprintf(snPhrase2, MsgStr(MSI_SUPERNOVICE4)); //FIXME: uncontrolled format string vulnerability

					if( m_recordChat[9] == snPhrase3 && m_recordChat[8] == snPhrase2 && m_recordChat[7] == snPhrase1 )
					{
						PACKET_CZ_CHOPOKGI packet;
						packet.PacketType = HEADER_CZ_CHOPOKGI;
						g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
					}
				}
			}

			if( strlen(chat2) > 6
			&& (chat2 == m_recordChat[i] || altMsg1 == m_recordChat[i] || altMsg2 == m_recordChat[i] || altMsg3 == m_recordChat[i] || altMsg4 == m_recordChat[i])
			&&  timeGetTime() - m_recordChatTime[i] < 30000 && timeGetTime() != m_recordChatTime[0] )
			{
				++nRepeats;
				if( nRepeats < 3 )
					continue;

				if( m_strikeNum == 3 )
				{
					m_strikeTime[0] = m_strikeTime[1];
					m_strikeTime[1] = m_strikeTime[2];
					m_strikeNum = 2;
				}

				m_strikeTime[m_strikeNum] = timeGetTime();

				if( m_strikeNum >= 2 && m_strikeTime[2] - m_strikeTime[0] < 90000 )
				{
					this->CGameMode::ChatDori();
					m_strikeNum = 0;
				}
				else
				if( m_strikeNum < 3 )
				{
					++m_strikeNum;
				}

				break;
			}
		}//for

		char chat[246+1];
		sprintf(chat, "%s : %s%s", g_session.CSession::GetCharName(), g_language->CLanguage::GetLanguageCharset(), g_windowMgr.UIWindowMgr::GetChatMsg());
		chat[sizeof(chat)-1] = '\0';
		size_t chatLen = strlen(chat);

		g_windowMgr.UIWindowMgr::ClearChatMsg();

		char buf[1024];
		PACKET_CZ_REQUEST_CHAT& packet = *(PACKET_CZ_REQUEST_CHAT*)buf;
		packet.PacketType = HEADER_CZ_REQUEST_CHAT;
		packet.PacketLength = sizeof(packet) + chatLen + 1;
		memcpy(packet.Text, chat, chatLen + 1);
		g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
	}
	break;
	case 7: //MM_BROADCASTMSG
	{
		int type = (int)val1;

		char chat2[246+1];
		strcpy(chat2, g_windowMgr.UIWindowMgr::GetChatMsg());
		g_insultFilter.CInsultFilter::IsGoodSentence(chat2);

		mystd::string chatMsg;
		if( type == 0 || type == 1 )
		{
			chatMsg = g_session.CSession::GetCharName() + mystd::string(": ") + g_windowMgr.UIWindowMgr::GetChatMsg();
		}
		else
		if( type == 4 || type == 5 )
		{
			chatMsg = mystd::string("blue") + g_windowMgr.UIWindowMgr::GetChatMsg();
		}
		else
		{
			chatMsg = g_windowMgr.UIWindowMgr::GetChatMsg();
		}

		char chat[246+1];
		strcpy(chat, chatMsg.c_str());
		chat[sizeof(chat)-1] = '\0';
		size_t chatLen = strlen(chat);

		if( strlen(g_windowMgr.UIWindowMgr::GetChatMsg()) != 0 )
		{
			char buf[1024];
			PACKET_CZ_BROADCAST& packet = *(PACKET_CZ_BROADCAST*)buf;
			packet.PacketType = ( type == 0 ) ? HEADER_CZ_BROADCAST
			                  : ( type == 1 ) ? HEADER_CZ_LOCALBROADCAST
			                  : ( type == 2 ) ? HEADER_CZ_BROADCAST
			                  : ( type == 3 ) ? HEADER_CZ_LOCALBROADCAST
			                  : ( type == 4 ) ? HEADER_CZ_BROADCAST
			                  : ( type == 5 ) ? HEADER_CZ_LOCALBROADCAST
			                  :                 packet.PacketType; // FIXME:uninitialized
			packet.PacketLength = sizeof(packet) + chatLen + 1;
			memcpy(packet.Text, chat, chatLen + 1);
			g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
		}

		g_windowMgr.UIWindowMgr::ClearChatMsg();
	}
	break;
//	case 8: //MM_QUERYCHARICTORINFO
//		//default (LoginMode only)
//	break;
	case 9: //MM_QUERYRSWNAME
		return (int)m_rswName;
	break;
	case 10: //MM_CONTACTNPC
	{
		CONTACTNPC* npc = (CONTACTNPC*)val1;

		Trace("MM_CONTACTNPC");
		m_world->m_player->SendMsg(NULL, 8, 0, 0, 0);

		if( npc->job == JT_WARPNPC )
		{
			if( m_noMove == 1 )
				break;

			m_noMove = 1;
			m_noMoveStartTick = timeGetTime();
		}

		PACKET_CZ_CONTACTNPC packet;
		packet.PacketType = HEADER_CZ_CONTACTNPC;
		packet.NAID = npc->nid;
		packet.type = npc->type;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 11: //MM_WHISPERMSG
	{
		const char* message = (const char*)val1;

		if( strlen(g_windowMgr.UIWindowMgr::GetChatMsg()) == 0 )
			break;
		if( g_session.CSession::IsEFST_Berserk() == 1 )
			break;

		char whisperChat2[222+1];
		strncpy(whisperChat2, g_windowMgr.UIWindowMgr::GetChatMsg(), sizeof(whisperChat2)-1); whisperChat2[sizeof(whisperChat2)] = '\0';

		if( g_insultFilter.CInsultFilter::IsBadSentence(whisperChat2) )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_NO_SEND_BECAUSE_INSULT), 0x0000FF, 0);
			g_windowMgr.UIWindowMgr::ClearChatMsg();
			break;
		}

		if( m_lastChat == whisperChat2 )
			++m_sameChatRepeatCnt;
		else
			m_sameChatRepeatCnt = 0;
		if( m_sameChatRepeatCnt >= 2 )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_NO_SAME_SENTANCE), 0x0000FF, 0);
			g_windowMgr.UIWindowMgr::ClearChatMsg();
			break;
		}

		m_lastChat = whisperChat2;

		char cName[24+1];
		memset(cName, 0, sizeof(cName));
		strcpy(cName, message);
		m_lastWhisperName = cName;

		if( strcmp(m_lastWhisperName.c_str(), g_session.CSession::GetCharName()) == 0 )
		{// talking to self
			g_windowMgr.UIWindowMgr::ClearChatMsg();
			break;
		}

		char whisperChat[222+1];
		strncpy(whisperChat, g_windowMgr.UIWindowMgr::GetChatMsg(), sizeof(whisperChat)-1); whisperChat[sizeof(whisperChat)-1] = '\0';
		m_lastWhisper = whisperChat;

		size_t whisperLen = strlen(whisperChat);
		if( whisperLen >= 222 ) // will never happen
		{
			g_windowMgr.UIWindowMgr::ClearChatMsg();
			break;
		}

		g_windowMgr.UIWindowMgr::ClearChatMsg();

		char buf[1024];
		PACKET_CZ_WHISPER& packet = *(PACKET_CZ_WHISPER*)buf;
		packet.PacketType = HEADER_CZ_WHISPER;
		packet.PacketLength = sizeof(packet) + whisperLen + 1;
		memcpy(packet.receiver, cName, sizeof(packet.receiver));
		memcpy(packet.Text, whisperChat, whisperLen + 1);
		g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
	}
	break;
	case 12: //MM_ADDREGISTERPOS
	{
		unsigned long pos = (unsigned long)val1;
		int x = (int)val2;
		int y = (int)val3;

		m_actorPosList[pos].x = x;
		m_actorPosList[pos].y = y;
	}
	break;
	case 13: //MM_DELETEREGISTERPOS
	{
		unsigned long pos = (unsigned long)val1;

		mystd::map<unsigned long,CellPos>::iterator it = m_actorPosList.find(pos);
		if( it != m_actorPosList.end() )
			m_actorPosList.erase(it);
	}
	break;
	case 14: //MM_DISCONNECT_CHARACTER
	{
		unsigned long aid = (unsigned long)val1;

		PACKET_CZ_DISCONNECT_CHARACTER packet;
		packet.PacketType = HEADER_CZ_DISCONNECT_CHARACTER;
		packet.AID = aid;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 15: //MM_DISCONNECT_ALL_CHARACTER
	{
		PACKET_CZ_DISCONNECT_ALL_CHARACTER packet;
		packet.PacketType = HEADER_CZ_DISCONNECT_ALL_CHARACTER;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 16: //MM_ITEMTHROW
	{
		unsigned short index = (unsigned short)val1;
		short count = (short)val2;

		if( m_waitingWearEquipAck + 2000 <= timeGetTime() && !m_waitingUseItemAck && !m_waitingItemThrowAck && index != 0 && !m_isPlayerDead )
		{
			m_waitingItemThrowAck = 1;

			PACKET_CZ_ITEM_THROW packet;
			packet.PacketType = HEADER_CZ_ITEM_THROW;
			packet.Index = index;
			packet.count = count;
			g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
		}

		this->SendMsg(MM_CANCEL_DRAG, 0, 0, 0);
	}
	break;
	case 17: //MM_BEGIN_DRAG_FROM_ITEMWND
	{
		int itemIndex = (int)val1;
		int num = (int)val2;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		ITEM_INFO itemInfo = g_session.CSession::GetItemInfoByIndex(itemIndex);
		if( !itemInfo.ITEM_INFO::IsValid() )
			break;

		m_dragInfo.m_isIdentified = itemInfo.m_isIdentified;
		m_dragInfo.m_numDragItem = num;
		m_dragInfo.m_dragType = DT_FROM_ITEMWND;
		m_dragInfo.m_dragItemIndex = itemIndex;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(itemInfo.m_itemName.c_str(), itemInfo.m_isIdentified);
		m_dragInfo.m_dragItemName = g_session.CSession::GetItemInfoByIndex(itemIndex).m_itemName;
		m_dragInfo.m_slotNum = -1;
		m_dragInfo.m_refiningLevel = itemInfo.m_refiningLevel;
		m_dragInfo.m_slot[0] = itemInfo.m_slot[0];
		m_dragInfo.m_slot[1] = itemInfo.m_slot[1];
		m_dragInfo.m_slot[2] = itemInfo.m_slot[2];
		m_dragInfo.m_slot[3] = itemInfo.m_slot[3];
	}
	break;
	case 18: //MM_DROP
	{
		int dropX = (int)val1;
		int dropY = (int)val2;

		if( m_dragInfo.m_dragType == DT_NODRAG )
		{
			break;
		}
		else
		if( m_dragInfo.m_dragType == DT_FROM_ITEMWND )
		{
			if( !g_session.CSession::IsValidItemIndexInUnequiped(m_dragInfo.m_dragItemIndex) || m_waitingWearEquipAck + 2000 > timeGetTime() )
			{
				m_dragInfo.m_dragType = DT_NODRAG;
				break;
			}
		}
		else
		if( m_dragInfo.m_dragType == DT_FROM_EQUIPWND )
		{
			if( !g_session.CSession::IsValidItemIndexInEquiped(m_dragInfo.m_dragItemIndex) )
			{
				m_dragInfo.m_dragType = DT_NODRAG;
				break;
			}
		}

		if( g_windowMgr.UIWindowMgr::Drop(dropX, dropY, &m_dragInfo) )
			break;

		if( m_dragInfo.m_dragType == DT_FROM_ITEMWND && g_windowMgr.UIWindowMgr::GetItemWnd() == NULL )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_OPEN_ITEMWND_TO_THROW), 0x0000FF, 0);
			this->SendMsg(MM_CANCEL_DRAG, 0, 0, 0);
			break;
		}

		UIExchangeWnd* exchangeWnd = g_windowMgr.UIWindowMgr::GetExchangeWnd();
		UIEquipWnd* equipWnd = g_windowMgr.UIWindowMgr::GetEquipWnd();
		UIItemStoreWnd* itemstoreWnd = g_windowMgr.UIWindowMgr::GetItemStoreWnd();
		if( exchangeWnd || equipWnd || itemstoreWnd || m_isOnQuest )
		{
			this->SendMsg(MM_CANCEL_DRAG, 0, 0, 0);

			if( !exchangeWnd && equipWnd && !itemstoreWnd )
			{
				g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
				g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_CLOSEEQUIPWND), 0x0000FF, 0);
			}

			break;
		}

		if( m_dragInfo.m_dragType != DT_FROM_ITEMWND )
		{
			this->SendMsg(MM_CANCEL_DRAG, 0, 0, 0);
			break;
		}

		if( g_session.CSession::GetEquipArrowIndex() == m_dragInfo.m_dragItemIndex )
		{
			ITEM_INFO itemInfo = g_session.CSession::GetItemInfoByIndex(m_dragInfo.m_dragItemIndex);
			if( itemInfo.ITEM_INFO::IsValid() )
			{
				this->SendMsg(MM_CANCEL_DRAG, 0, 0, 0);
				g_windowMgr.UIWindowMgr::ErrorMsg(MsgStr(MSI_UNEQUIP_ARROW), 0, TRUE, 0, 0);
				break;
			}
		}

		if( m_dragInfo.m_numDragItem == DT_FROM_ITEMWND )
		{
			this->SendMsg(MM_ITEMTHROW, m_dragInfo.m_dragItemIndex, 1, 0);
		}
		else
		{
			g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 1);
			g_windowMgr.UIWindowMgr::GetItemDropCntWnd()->SendMsg(NULL, 13, 0, 0, 0);
		}
	}
	break;
	case 19: //MM_CANCEL_DRAG
		m_dragInfo.m_dragType = DT_NODRAG;
		m_dragInfo.m_dragItemIndex = 0;
		m_dragInfo.m_numDragItem = 0;
		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
	break;
	case 20: //MM_WEAR_EQUIP
	{
		int index = (int)val1;
		int wearLocation = (int)val2;

		if( m_waitingWearEquipAck + 2000 > timeGetTime() || m_isPlayerDead )
			break;

		int slotNum[3];
		g_session.CSession::BitMaskToSlotNum(wearLocation, slotNum);

		ITEM_INFO itemInfo = g_session.CSession::GetEquipedItems(slotNum[0]);
		if( itemInfo.m_isDamaged )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_DAMAGED_ITEM), 0x0000FF, 0);
			break;
		}

		int slotNum2[3];
		if( itemInfo.m_itemIndex != 0 && itemInfo.m_num == 1 )
			g_session.CSession::BitMaskToSlotNum(itemInfo.m_wearLocation, slotNum2);

		m_waitingWearEquipAck = timeGetTime();

		PACKET_CZ_REQ_WEAR_EQUIP packet;
		packet.PacketType = HEADER_CZ_REQ_WEAR_EQUIP;
		packet.index = index;
		packet.wearLocation = wearLocation;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 21: //MM_TAKE_OFF_EQUIP
	{
		int wearLocation = (int)val1;

		if( m_waitingTakeoffEquipAck + 2000 > timeGetTime() )
			break;

		if( m_isPlayerDead )
			break;

		ITEM_INFO itemInfo = g_session.CSession::GetEquipedItems(wearLocation);
		if( itemInfo.m_itemIndex == 0 || itemInfo.m_num <= 0 )
			break;

		m_waitingTakeoffEquipAck = timeGetTime();

		PACKET_CZ_REQ_TAKEOFF_EQUIP packet;
		packet.PacketType = HEADER_CZ_REQ_TAKEOFF_EQUIP;
		packet.index = static_cast<unsigned short>(itemInfo.m_itemIndex);
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);

		return 1; //!?
	}
	break;
	case 22: //MM_BEGIN_DRAG_FROM_EQUIPMWND
	{
		int wearLocation = (int)val1;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		int slotNum[3];
		g_session.CSession::BitMaskToSlotNum(wearLocation, slotNum);

		ITEM_INFO itemInfo = g_session.CSession::GetEquipedItems(slotNum[0]);
		if( !itemInfo.ITEM_INFO::IsValid() )
			break;

		m_dragInfo.m_dragItemIndex = itemInfo.m_itemIndex;
		m_dragInfo.m_isIdentified = itemInfo.m_isIdentified;
		m_dragInfo.m_numDragItem = itemInfo.m_num;
		m_dragInfo.m_dragType = DT_FROM_EQUIPWND;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(itemInfo.m_itemName.c_str(), itemInfo.m_isIdentified);
		m_dragInfo.m_slotNum = slotNum[0];
		m_dragInfo.m_refiningLevel = itemInfo.m_refiningLevel;
		m_dragInfo.m_slot[0] = itemInfo.m_slot[0];
		m_dragInfo.m_slot[1] = itemInfo.m_slot[1];
		m_dragInfo.m_slot[2] = itemInfo.m_slot[2];
		m_dragInfo.m_slot[3] = itemInfo.m_slot[3];
	}
	break;
	case 23: //MM_ITEMTHROW_THROUGH_DROPCNTWND
	{
		int index = (int)val1;

		this->SendMsg(MM_ITEMTHROW, m_dragInfo.m_dragItemIndex, index, 0);
	}
	break;
	case 24: //MM_REQ_NEXT_SCRIPT
	{
		unsigned long npcaid = (unsigned long)val1;

		PACKET_CZ_REQ_NEXT_SCRIPT packet;
		packet.PacketType = HEADER_CZ_REQ_NEXT_SCRIPT;
		packet.NAID = npcaid;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 25: //MM_CHOOSE_MENU
	{
		unsigned char num = (unsigned char)val1;
		unsigned long npcid = (unsigned long)val2;

		PACKET_CZ_CHOOSE_MENU packet;
		packet.PacketType = HEADER_CZ_CHOOSE_MENU;
		packet.NAID = npcid;
		packet.num = num;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 26: //MM_MENUSELECTED
	{
		int menuId = (int)val1;

		if( g_windowMgr.UIWindowMgr::GetMenu() != NULL )
			g_windowMgr.UIWindowMgr::DeleteWindow(WID_MENUWND);

		if( g_windowMgr.UIWindowMgr::GetItemStoreWnd() != NULL )
			break;

		switch( m_menuIdList[menuId] )
		{
		case 4:
			if( g_modeMgr.CModeMgr::GetGameMode()->m_world->m_player->CGameActor::GetEffectState() == 2 )
				break;
			this->SendMsg(MM_REQ_EXCHANGE_ITEM, m_menuTargetAID, 0, 0);
		break;
		case 5:
			this->SendMsg(MM_REQ_JOIN_GROUP, m_menuTargetAID, 0, 0);
		break;
		case 10:
		{
			NamePair& np = m_actorNameList.insert(mystd::pair<unsigned long,NamePair>(m_menuTargetAID, NamePair())).first->second;
			g_windowMgr.UIWindowMgr::AddFriendCharName(np.cName.c_str());
		}
		break;
		case 11:
			g_windowMgr.UIWindowMgr::WriteWhisperChatToFile(m_lastWhisperMenuCharacterName.c_str());
		break;
		case 12:
		{
			NamePair& np1 = m_actorNameList.insert(mystd::pair<unsigned long,NamePair>(m_menuTargetAID, NamePair())).first->second;
			this->CGameMode::ProcessTalkType(TT_REQ_WHISPER_PC_EX, (int)&np1);

			NamePair& np2 = m_actorNameList.insert(mystd::pair<unsigned long,NamePair>(m_menuTargetAID, NamePair())).first->second;
			g_session.CSession::AddToExNameList(np2.cName.c_str());
			g_session.CSession::AddToExAidList(m_menuTargetAID);
		}
		break;
		case 13:
		{
			NamePair& np1 = m_actorNameList.insert(mystd::pair<unsigned long,NamePair>(m_menuTargetAID, NamePair())).first->second;
			this->CGameMode::ProcessTalkType(TT_REQ_WHISPER_PC_IN, (int)&np1);

			NamePair& np2 = m_actorNameList.insert(mystd::pair<unsigned long,NamePair>(m_menuTargetAID, NamePair())).first->second;
			g_session.CSession::DeleteFromExNameList(np2.cName.c_str());
			g_session.CSession::DeleteFromExAidList(m_menuTargetAID);
		}
		break;
		case 20:
		{
			NamePair& np = m_actorNameList.insert(mystd::pair<unsigned long,NamePair>(m_menuTargetAID, NamePair())).first->second;
			g_windowMgr.UIWindowMgr::SendMsg(UIM_MAKE_WHISPER_WINDOW, (int)np.cName.c_str(), 0, 0);
		}
		break;
		case 21:
			g_windowMgr.UIWindowMgr::AddFriendCharName(m_lastWhisperMenuCharacterName.c_str());
		break;
		case 22:
			this->SendMsg(MM_REQ_JOIN_GUILD, m_menuTargetAID, 0, 0);
		break;
		case 23:
		{
			if( !IsNameYellow(g_session.CSession::GetAid()) )
				break;

			UICntWnd* wnd = new UICntWnd();
			wnd->UIWindow::Create(182, 46);
			wnd->Move((g_renderer->CRenderer::GetWidth() - 640) / 2 + 200, 200 * g_renderer->CRenderer::GetHeight() / 480);
			g_windowMgr.UIWindowMgr::AddWindow(wnd);
			wnd->SendMsg(NULL, 80, 164, 0, 0);
			wnd->SendMsg(NULL, 29, (int)MsgStr(MSI_GIVE_PLUS_MANNER_POINT), 0, 0);
			wnd->SendMsg(NULL, 81, 1, 0, 0);
		}
		break;
		case 24:
		{
			if( !IsGravityAid(g_session.CSession::GetAid()) )
				break;

			UICntWnd* wnd = new UICntWnd();
			wnd->UIWindow::Create(182, 46);
			wnd->Move((g_renderer->CRenderer::GetWidth() - 640) / 2 + 200, 200 * g_renderer->CRenderer::GetHeight() / 480);
			g_windowMgr.UIWindowMgr::AddWindow(wnd);
			wnd->SendMsg(0, 80, 165, 0, 0);
			wnd->SendMsg(0, 29, (int)MsgStr(MSI_GIVE_MINUS_MANNER_POINT), 0, 0);
			wnd->SendMsg(0, 81, 1, 0, 0);
		}
		break;
		case 25:
			this->SendMsg(MM_REQ_ALLY_GUILD, m_menuTargetAID, 0, 0);
		break;
		case 26:
			this->SendMsg(MM_REQ_HOSTILE_GUILD, m_menuTargetAID, 0, 0);
		break;
		case 28:
			this->SendMsg(MM_DISCONNECT_CHARACTER, m_menuTargetAID, 0, 0);
		break;
		case 29:
			if( g_windowMgr.UIWindowMgr::ErrorMsg(MsgStr(MSI_SURE_TO_FEED_PET), 2, 0, 0, 0) != 97 )
				break;
			this->SendMsg(MM_COMMAND_PET, 1, 0, 0);
		break;
		case 30:
			this->SendMsg(MM_COMMAND_PET, 2, 0, 0);
		break;
		case 31:
		{
			this->SendMsg(MM_COMMAND_PET, 3, 0, 0);

			ITEM_INFO itemInfo = g_session.CSession::GetItemInfoByIndex(g_session.m_petEggIndex);
			itemInfo.m_isDamaged = 0;
			g_session.CSession::SetItem(&itemInfo);

			g_session.m_petEggIndex = -1;
			g_session.m_petJob = -1;

			if( g_windowMgr.UIWindowMgr::GetItemWnd() )
				g_windowMgr.UIWindowMgr::GetItemWnd()->Invalidate();

			g_windowMgr.UIWindowMgr::DeleteWindow(WID_PETINFOWND);
		}
		break;
		case 32:
			this->SendMsg(MM_COMMAND_PET, 4, 0, 0);
		break;
		case 33:
			this->SendMsg(MM_COMMAND_PET, 0, 0, 0);
			if( g_windowMgr.UIWindowMgr::DeleteWindow(WID_PETINFOWND) )
				break;
			g_windowMgr.UIWindowMgr::MakeWindow(WID_PETINFOWND);
		break;
		case 34:
		{
			char msg[128];
			sprintf(msg, "%s : %d (GID)", g_session.m_lastServerName.c_str(), m_menuTargetAID);
			g_language->CLanguage::SetInput(msg); //inlined
		}
		break;
		case 35:
			g_windowMgr.UIWindowMgr::MakeWindow(WID_PROHIBITLISTWND)->SendMsg(0, 34, m_menuTargetAID, 0, 0);
		break;
		default:
		break;
		}
	}
	break;
	case 27: //MM_RESTART
	{
		unsigned char type = (unsigned char)val1;

		PACKET_CZ_RESTART packet;
		packet.PacketType = HEADER_CZ_RESTART;
		packet.type = type;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 28: //MM_SETLOCKONMOUSE
	{
		int isMouseLockOn = (int)val1;

		m_isMouseLockOn = isMouseLockOn;

		if( isMouseLockOn == 0 )
		{
			m_lastPcGid = 0;
			m_lastMonGid = 0;
		}
	}
	break;
	case 29: //MM_USEITEM
	{
		unsigned short index = (unsigned short)val1;

		if( m_waitingUseItemAck || m_waitingItemThrowAck || index == 0 || m_isPlayerDead )
			break;
		
		int effectState = m_world->m_player->CGameActor::GetEffectState();
		int bodyState = m_world->m_player->CGameActor::GetBodyState();
		if( IsEffectStateBurrow(effectState) || bodyState == 1 || bodyState == 2 || bodyState == 3 || bodyState == 4 )
			break;

		ITEM_INFO itemInfo = g_session.CSession::GetItemInfoByIndex(val1);
		int itemId = itemInfo.ITEM_INFO::GetItemId();
		if( m_world->m_player->m_stateId == STATEID_SIT && (itemId == ITEM_WING_OF_FLY || itemId == ITEM_WING_OF_BUTTERFLY || itemId == ITEM_SPECTACLES) )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_CANT_USE_WHEN_SITDOWN), 0x0000FF, 0);
			break;
		}

		if( (m_world->CWorld::IsPKZone() || m_world->CWorld::IsEventPVPMode()) && (itemId == ITEM_WING_OF_FLY || itemId == ITEM_WING_OF_BUTTERFLY) )
			break;

		m_waitingUseItemAck = 1;

		PACKET_CZ_USE_ITEM packet;
		packet.PacketType = HEADER_CZ_USE_ITEM;
		packet.index = index;
		packet.AID = g_session.CSession::GetAid();
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
//	case 30: //MM_GOTOIDENTRY
//		//default (LoginMode only)
//	break;
	case 31: //MM_REQ_STATUS
	{
		if( m_waitingReqStatusAck )
			break;
		m_waitingReqStatusAck = TRUE;

		if( m_isPlayerDead )
			break;

		PACKET_CZ_REQ_STATUS packet;
		packet.PacketType = HEADER_CZ_REQ_STATUS;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 32: //MM_STATUS_CHANGE
	{
		unsigned short statusID = (unsigned short)val1;
		unsigned char changeAmount = (unsigned char)val2;

		if( m_waitingReqStatusAck )
			break;
		m_waitingReqStatusAck = TRUE;

		if( m_isPlayerDead )
			break;

		PACKET_CZ_STATUS_CHANGE packet;
		packet.PacketType = HEADER_CZ_STATUS_CHANGE;
		packet.statusID = statusID;
		packet.changeAmount = changeAmount;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 33: //MM_REQ_EMOTION
	{
		unsigned char type = (unsigned char)val1;

		if( m_isReqEmotion || timeGetTime() <= m_reqEmotionTick + 2500 )
			break;

		m_reqEmotionTick = timeGetTime();
		m_isReqEmotion = TRUE;

		PACKET_CZ_REQ_EMOTION packet;
		packet.PacketType = HEADER_CZ_REQ_EMOTION;
		packet.type = type;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 34: //MM_REQ_NUM_USER
	{
		PACKET_CZ_REQ_USER_COUNT packet;
		packet.PacketType = HEADER_CZ_REQ_USER_COUNT;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 35: //MM_PLAYER_EMOTION_END
		m_isReqEmotion = 0;
	break;
	case 36: //MM_BEGIN_DRAG_FROM_ITEMSHOPWND
	{
		ITEM_INFO& drag = *(ITEM_INFO*)val1;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		ITEM_INFO itemInfo = g_session.CSession::GetItemInfoByIndex(drag.m_itemIndex);
		m_dragInfo.m_dragType = DT_FROM_ITEMSHOPWND;
		m_dragInfo.m_dragItemIndex = drag.m_itemIndex;
		m_dragInfo.m_numDragItem = ( itemInfo.m_itemIndex == 0 ) ? 1 : drag.m_num;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(drag.m_itemName.c_str(), drag.m_isIdentified);
		m_dragInfo.m_dragItemName = drag.m_itemName.c_str();
		m_dragInfo.m_dragItemType = drag.m_itemType;
		m_dragInfo.m_dragItemPrice = drag.m_price;
		m_dragInfo.m_dragItemRealPrice = drag.m_realPrice;
		m_dragInfo.m_refiningLevel = drag.m_refiningLevel;
		m_dragInfo.m_isIdentified = drag.m_isIdentified;
		m_dragInfo.m_slotNum = -1;
		m_dragInfo.m_slot[0] = drag.m_slot[0];
		m_dragInfo.m_slot[1] = drag.m_slot[1];
		m_dragInfo.m_slot[2] = drag.m_slot[2];
		m_dragInfo.m_slot[3] = drag.m_slot[3];
	}
	break;
	case 37: //MM_REQ_PURCHASE
	{
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_ITEMSHOPWND);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_ITEMPURCHASEWND);
		int numItem = g_session.CSession::GetNumPurchaseItem();

		char buf[2048];
		PACKET_CZ_PC_PURCHASE_ITEMLIST& packet = *(PACKET_CZ_PC_PURCHASE_ITEMLIST*)buf;
		packet.PacketType = HEADER_CZ_PC_PURCHASE_ITEMLIST;
		packet.PacketLength = sizeof(packet) + numItem * sizeof(packet.Item[0]);

		if( packet.PacketLength > sizeof(buf) )
			break;

		int n = 0;
		for( int i = 0; i < numItem; ++i )
		{
			ITEM_INFO itemInfo = g_session.CSession::GetPurchaseItemInfoBySequence(i); //FIXME: IsValid not checked

			PACKET_CZ_PC_PURCHASE_ITEMLIST::CZ_PURCHASE_ITEM Item;
			Item.count = static_cast<short>(itemInfo.m_num);
			Item.index = static_cast<short>(atoi(itemInfo.m_itemName.c_str()));

			packet.Item[n] = Item;
			++n;
		}

		if( numItem != 0 && !m_isPlayerDead ) //FIXME: should check 'n' instead
			g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);

		g_session.CSession::ClearDealItems();
	}
	break;
	case 38: //MM_REQ_SELL
	{
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_ITEMSHOPWND);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_ITEMSELLWND);
		int numItem = g_session.CSession::GetNumSellItem();

		char buf[2048];
		PACKET_CZ_PC_SELL_ITEMLIST& packet = *(PACKET_CZ_PC_SELL_ITEMLIST*)buf;
		packet.PacketType = HEADER_CZ_PC_SELL_ITEMLIST;
		packet.PacketLength = sizeof(packet) + numItem * sizeof(packet.Item[0]);

		if( packet.PacketLength > sizeof(buf) )
			break;

		int n = 0;
		for( int i = 0; i < numItem; ++i )
		{
			ITEM_INFO itemInfo = g_session.CSession::GetSellItemInfoBySequence(i); //FIXME: IsValid not checked

			PACKET_CZ_PC_SELL_ITEMLIST::CZ_SELL_ITEM Item;
			Item.count = static_cast<short>(itemInfo.m_num);
			Item.index = static_cast<short>(itemInfo.m_itemIndex);

			packet.Item[n] = Item;
			++n;
		}

		if( numItem != 0 && !m_isPlayerDead ) //FIXME: should check 'n' instead
			g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);

		g_session.CSession::ClearDealItems();
	}
	break;
	case 39: //MM_REQ_ITEM_EXPLANATION_BYNAME
	break;
	case 40: //MM_ACK_SELL
	{
		unsigned long npcid = (unsigned long)val1;

		PACKET_CZ_ACK_SELECT_DEALTYPE packet;
		packet.PacketType = HEADER_CZ_ACK_SELECT_DEALTYPE;
		packet.NAID = npcid;
		packet.type = DEALTYPE_SELL;
		if( !m_isPlayerDead )
			g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 41: //MM_ACK_BUY
	{
		unsigned long npcid = (unsigned long)val1;

		PACKET_CZ_ACK_SELECT_DEALTYPE packet;
		packet.PacketType = HEADER_CZ_ACK_SELECT_DEALTYPE;
		packet.NAID = npcid;
		packet.type = DEALTYPE_PURCHASE;
		if( !m_isPlayerDead )
			g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
//	case 42: //MM_REFRESH_SHOPWND
//		//default (unused)
//	break;
	case 43: //MM_RELEASE_QUEST
		m_isOnQuest = 0;
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_SAYDIALOGWND);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_CHOOSEWND);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_CHOOSESELLBUYWND);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_ITEMSHOPWND);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_ITEMPURCHASEWND);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_ITEMSELLWND);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_MERCHANTITEMSHOPWND);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_MERCHANTITEMPURCHASEWND);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_ITEMCOLLECTIONWND);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_ITEMPARAMCHANGEDISPLAYWND);
		this->SendMsg(MM_SHOW_IMAGE, (int)"", -1, 0);
	break;
	case 44: //MM_BEGIN_DRAG_FROM_ITEMPURCHASEWND
	{
		const char* itemName = (const char*)val1;
		int itemPrice = (int)val2;
		int itemIndex = (int)val3;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		ITEM_INFO itemInfo = g_session.CSession::GetPurchaseItemInfoByName(itemName);
		if( itemInfo.m_itemIndex == 0 )
			break;

		m_dragInfo.m_isIdentified = itemInfo.m_isIdentified;
		m_dragInfo.m_dragItemIndex = itemIndex;
		m_dragInfo.m_dragType = DT_FROM_ITEMPURCHASEWND;
		m_dragInfo.m_numDragItem = itemInfo.m_num;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(itemName, itemInfo.m_isIdentified);
		m_dragInfo.m_dragItemName = itemName;
		m_dragInfo.m_dragItemPrice = itemPrice;
		m_dragInfo.m_dragItemRealPrice = itemInfo.m_realPrice;
		m_dragInfo.m_numDragItem = itemInfo.m_num;
		m_dragInfo.m_slotNum = -1;
		m_dragInfo.m_refiningLevel = itemInfo.m_refiningLevel;
		m_dragInfo.m_slot[0] = itemInfo.m_slot[0];
		m_dragInfo.m_slot[1] = itemInfo.m_slot[1];
		m_dragInfo.m_slot[2] = itemInfo.m_slot[2];
		m_dragInfo.m_slot[3] = itemInfo.m_slot[3];
	}
	break;
	case 45: //MM_BEGIN_DRAG_FROM_ITEMSELLWND
	{
		const char* itemName = (const char*)val1;
		int itemPrice = (int)val2;
		int itemIndex = (int)val3;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		ITEM_INFO itemInfo = g_session.CSession::GetSellItemInfoByIndex(itemIndex);
		if( itemInfo.m_itemIndex == 0 )
			break;

		m_dragInfo.m_isIdentified = itemInfo.m_isIdentified;
		m_dragInfo.m_dragType = DT_FROM_ITEMSELLWND;
		m_dragInfo.m_dragItemIndex = itemIndex;
		m_dragInfo.m_numDragItem = itemInfo.m_num;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(itemName, itemInfo.m_isIdentified);
		m_dragInfo.m_dragItemName = itemName;
		m_dragInfo.m_dragItemPrice = itemPrice;
		m_dragInfo.m_dragItemRealPrice = itemInfo.m_realPrice;
		m_dragInfo.m_numDragItem = itemInfo.m_num;
		m_dragInfo.m_slotNum = -1;
		m_dragInfo.m_refiningLevel = itemInfo.m_refiningLevel;
		m_dragInfo.m_slot[0] = itemInfo.m_slot[0];
		m_dragInfo.m_slot[1] = itemInfo.m_slot[1];
		m_dragInfo.m_slot[2] = itemInfo.m_slot[2];
		m_dragInfo.m_slot[3] = itemInfo.m_slot[3];
	}
	break;
	case 46: //MM_TOGGLE_PLAYERGAGE
		if( m_playerGage != NULL )
		{
			g_windowMgr.UIWindowMgr::PostQuit(m_playerGage);
			m_playerGage = NULL;
		}
		else
		{
			m_playerGage = new UIPlayerGage();
			m_playerGage->UIWindow::Create(60, 9);
			m_playerGage->Move(m_world->m_player->m_lastTlvertX - 30, m_world->m_player->m_lastTlvertY + int(12 * g_renderer->CRenderer::GetHeight() / 480 * m_world->m_player->m_lastPixelRatio));
			g_windowMgr.UIWindowMgr::AddWindowFront(m_playerGage);
		}
	break;
	case 47: //MM_PROCESS_TALK_TYPE
		this->CGameMode::ProcessTalkType(val1, val2);
	break;
	case 48: //MM_CREATE_CHATROOM
	{
		ChatRoomInfo* info = (ChatRoomInfo*)val1;

		m_lastChatroomInfo.title = info->title;
		m_lastChatroomInfo.roomType = info->roomType;
		m_lastChatroomInfo.numPeople = info->numPeople;
		m_lastChatroomInfo.maxNumPeople = info->maxNumPeople;
		m_lastChatroomInfo.roomId = info->roomId;
		m_lastChatroomInfo.pass = info->pass;

		char buf[1024];
		PACKET_CZ_CREATE_CHATROOM& packet = *(PACKET_CZ_CREATE_CHATROOM*)buf;
		packet.PacketType = HEADER_CZ_CREATE_CHATROOM;
		packet.PacketLength = sizeof(packet) + info->title.size();
		packet.size = info->maxNumPeople;
		packet.type = info->roomType;
		memset(packet.passwd, '\0', sizeof(packet.passwd));
		memcpy(packet.passwd, info->pass.c_str(), info->pass.size());
		memcpy(packet.title, info->title.c_str(), info->title.size());
		g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
	}
	break;
	case 49: //MM_CHANGE_CHATROOM
	{
		ChatRoomInfo* info = (ChatRoomInfo*)val1;

		if( g_windowMgr.UIWindowMgr::GetChatRoom() == NULL )
			break;

		m_lastChatroomInfo.title = info->title;
		m_lastChatroomInfo.roomType = info->roomType;
		m_lastChatroomInfo.numPeople = info->numPeople;
		m_lastChatroomInfo.maxNumPeople = info->maxNumPeople;
		m_lastChatroomInfo.roomId = info->roomId;
		m_lastChatroomInfo.pass = info->pass;

		char buf[1024];
		PACKET_CZ_CHANGE_CHATROOM& packet = *(PACKET_CZ_CHANGE_CHATROOM*)buf;
		packet.PacketType = HEADER_CZ_CHANGE_CHATROOM;
		packet.PacketLength = sizeof(packet) + info->title.size();
		packet.size = info->maxNumPeople;
		packet.type = info->roomType;
		memset(packet.passwd, '\0', sizeof(packet.passwd));
		memcpy(packet.passwd, info->pass.c_str(), info->pass.size());
		memcpy(packet.title, info->title.c_str(), info->title.size());
		g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
	}
	break;
	case 50: //MM_REQ_ENTER_ROOM
	{
		unsigned long roomID = (unsigned long)val1;
		const char* password = (const char*)val2;

		if( timeGetTime() > m_reqTickChatRoom + 1000 )
			m_isWaitingEnterRoom = 0;

		if( g_windowMgr.UIWindowMgr::GetChatRoom() != NULL || m_isWaitingEnterRoom )
			break;

		m_isWaitingEnterRoom = 1;
		m_reqTickChatRoom = timeGetTime();

		PACKET_CZ_REQ_ENTER_ROOM packet;
		packet.PacketType = HEADER_CZ_REQ_ENTER_ROOM;
		packet.roomID = roomID;
		if( password != NULL )
		{
			char passwd[8+1];
			strcpy(passwd, password);
			memcpy(packet.passwd, passwd, sizeof(packet.passwd));
		}
		else
		{
			memset(packet.passwd, '\0', sizeof(packet.passwd));
		}
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 51: //MM_REQ_ROLE_CHANGE
	{
		const char* memberName = (const char*)val1;
		unsigned long role = (unsigned long)val2;
		char name[24+1];

		PACKET_CZ_REQ_ROLE_CHANGE packet;
		packet.PacketType = HEADER_CZ_REQ_ROLE_CHANGE;
		packet.role = role;
		strcpy(name, memberName);
		memcpy(packet.name, name, sizeof(packet.name));
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 52: //MM_REQ_EXPEL_MEMBER
	{
		const char* memberName = (const char*)val1;
		char name[24+1];

		PACKET_CZ_REQ_EXPEL_MEMBER packet;
		packet.PacketType = HEADER_CZ_REQ_EXPEL_MEMBER;
		strcpy(name, memberName);
		memcpy(packet.name, name, sizeof(packet.name));
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 53: //MM_REQ_EXIT_ROOM
	{
		if( g_windowMgr.UIWindowMgr::GetChatRoom() == NULL )
			return 0;

		PACKET_CZ_EXIT_ROOM packet;
		packet.PacketType = HEADER_CZ_EXIT_ROOM;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 54: //MM_REQ_EXCHANGE_ITEM
	{
		unsigned long AID = (unsigned long)val1;

		this->SendMsg(MM_RELEASE_QUEST, 0, 0, 0);
		g_session.CSession::ClearDealItems();

		if( m_actorNameList.find(AID) != m_actorNameList.end() )
			break;

		m_lastExchangeCharacterName = m_actorNameList[AID].cName;

		PACKET_CZ_REQ_EXCHANGE_ITEM packet;
		packet.PacketType = HEADER_CZ_REQ_EXCHANGE_ITEM;
		packet.AID = AID;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 55: //MM_ACK_EXCHANGE_ITEM
	{
		unsigned char result = (unsigned char)val1;

		this->SendMsg(MM_RELEASE_QUEST, 0, 0, 0);
		g_session.CSession::ClearDealItems();

		PACKET_CZ_ACK_EXCHANGE_ITEM packet;
		packet.PacketType = HEADER_CZ_ACK_EXCHANGE_ITEM;
		packet.result = result;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 56: //MM_ADD_EXCHANGE_ITEM
	{
		int index = (int)val1;
		int count = (int)val2;

		if( g_session.CSession::IsExistIndexInMyChangeList(index) )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_CAN_DRAG_ITEM_OLNY_ONETIME), 0x0000FF, 0);
			break;
		}

		if( g_session.CSession::IsExchangeItemListFull() && index != 0 )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_MAXEXCHANGE_IS_10_KIND), 0x0000FF, 0);
			break;
		}

		if( m_isWaitingAddExchangeItem )
			break;
		m_isWaitingAddExchangeItem = TRUE;

		m_exchangeItemCnt = count;

		PACKET_CZ_ADD_EXCHANGE_ITEM packet;
		packet.PacketType = HEADER_CZ_ADD_EXCHANGE_ITEM;
		packet.index = index;
		packet.count = count;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 57: //MM_CONCLUDE_EXCHANGE_ITEM
	{
		PACKET_CZ_CONCLUDE_EXCHANGE_ITEM packet;
		packet.PacketType = HEADER_CZ_CONCLUDE_EXCHANGE_ITEM;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 58: //MM_CANCEL_EXCHANGE_ITEM
	{
		PACKET_CZ_CANCEL_EXCHANGE_ITEM packet;
		packet.PacketType = HEADER_CZ_CANCEL_EXCHANGE_ITEM;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 59: //MM_EXEC_EXCHANGE_ITEM
	{
		PACKET_CZ_EXEC_EXCHANGE_ITEM packet;
		packet.PacketType = HEADER_CZ_EXEC_EXCHANGE_ITEM;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 60: //MM_BEGIN_DRAG_FROM_ITEMSTOREWND
	{
		int itemIndex = (int)val1;
		int num = (int)val2;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		ITEM_INFO itemInfo = g_session.CSession::GetStoreItemInfoByIndex(itemIndex);
		if( !itemInfo.ITEM_INFO::IsValid() )
			break;

		m_dragInfo.m_dragType = DT_FROM_ITEMSTOREWND;
		m_dragInfo.m_numDragItem = num;
		m_dragInfo.m_isIdentified = itemInfo.m_isIdentified;
		m_dragInfo.m_dragItemIndex = itemIndex;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(itemInfo.m_itemName.c_str(), itemInfo.m_isIdentified);
		m_dragInfo.m_dragItemName = itemInfo.m_itemName;
		m_dragInfo.m_slotNum = -1;
		m_dragInfo.m_refiningLevel = itemInfo.m_refiningLevel;
		m_dragInfo.m_slot[0] = itemInfo.m_slot[0];
		m_dragInfo.m_slot[1] = itemInfo.m_slot[1];
		m_dragInfo.m_slot[2] = itemInfo.m_slot[2];
		m_dragInfo.m_slot[3] = itemInfo.m_slot[3];
	}
	break;
	case 61: //MM_ADD_ITEM_TO_STORE
	{
		short index = (short)val1;
		int count = (int)val2;

		PACKET_CZ_MOVE_ITEM_FROM_BODY_TO_STORE packet;
		packet.PacketType = HEADER_CZ_MOVE_ITEM_FROM_BODY_TO_STORE;
		packet.index = index;
		packet.count = count;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 62: //MM_MOVE_ITEM_FROM_STORE_TO_BODY
	{
		short index = (short)val1;
		int count = (int)val2;

		PACKET_CZ_MOVE_ITEM_FROM_STORE_TO_BODY packet;
		packet.PacketType = HEADER_CZ_MOVE_ITEM_FROM_STORE_TO_BODY;
		packet.index = index;
		packet.count = count;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 63: //MM_CLOSE_STORE
	{
		PACKET_CZ_CLOSE_STORE packet;
		packet.PacketType = HEADER_CZ_CLOSE_STORE;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 64: //MM_MAKE_GROUP
	{
		const char* groupName = (const char*)val1;

		PACKET_CZ_MAKE_GROUP packet;
		packet.PacketType = HEADER_CZ_MAKE_GROUP;
		if( strlen(groupName) >= sizeof(packet.groupName) )
		{
			g_windowMgr.UIWindowMgr::ErrorMsg(MsgStr(MSI_NAMELENGTH_TOO_LONG), 0, TRUE, 0, 0);
			break;
		}
		strncpy(packet.groupName, groupName, sizeof(packet.groupName));
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 65: //MM_REQ_JOIN_GROUP
	{
		unsigned long aid = (unsigned long)val1;

		PACKET_CZ_REQ_JOIN_GROUP packet;
		packet.PacketType = HEADER_CZ_REQ_JOIN_GROUP;
		packet.AID = aid;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 66: //MM_JOIN_GROUP
	{
		unsigned long groupid = (unsigned long)val1;
		int answer = (int)val2;

		if( answer )
			g_windowMgr.UIWindowMgr::MakeWindow(WID_MESSENGERGROUPWND);
		else
			g_session.m_partyName = "";

		PACKET_CZ_JOIN_GROUP packet;
		packet.PacketType = HEADER_CZ_JOIN_GROUP;
		packet.GRID = groupid;
		packet.answer = answer;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 67: //MM_REQ_LEAVE_GROUP
	{
		PACKET_CZ_REQ_LEAVE_GROUP packet;
		packet.PacketType = HEADER_CZ_REQ_LEAVE_GROUP;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 68: //MM_REQ_EXPEL_GROUP_MEMBER
	{
		const char* memberName = (const char*)val1;

		if( !g_session.m_amIPartyMaster )
			break;

		PACKET_CZ_REQ_EXPEL_GROUP_MEMBER packet;
		packet.PacketType = HEADER_CZ_REQ_EXPEL_GROUP_MEMBER;
		packet.AID = g_session.CSession::GetPartyInfoByName(memberName).AID;
		strncpy(packet.characterName, memberName, sizeof(packet.characterName)); //FIXME: zero terminator
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 69: //MM_ADDPARTYPOS
	{
		unsigned long AID = (unsigned long)val1;
		int x = (int)val2;
		int y = (int)val3;

		m_partyPosList[AID].x = x;
		m_partyPosList[AID].y = y;
		m_partyPosList[AID].color = g_session.CSession::GetPartyInfoByAid(AID).color;
	}
	break;
	case 70: //MM_DELETEPARTYPOS
	{
		unsigned long pos = (unsigned long)val1;

		mystd::map<unsigned long,ColorCellPos>::iterator it = m_partyPosList.find(pos);
		if( it != m_partyPosList.end() )
			m_partyPosList.erase(it);
	}
	break;
	case 71: //MM_DELETEPARTYPOSALL
		m_partyPosList.clear();
	break;
	case 72: //MM_CHAT_PARTY
	{
		if( strlen(g_windowMgr.UIWindowMgr::GetChatMsg()) == 0 )
			break;
		if( g_session.CSession::IsEFST_Berserk() == 1 )
			break;

		char chat2[246+1];
		strcpy(chat2, g_windowMgr.UIWindowMgr::GetChatMsg());

		if( g_insultFilter.CInsultFilter::IsBadSentence(chat2) )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_NO_SEND_BECAUSE_INSULT), 0x0000FF, 0);
			g_windowMgr.UIWindowMgr::ClearChatMsg();
			break;
		}

		if( m_lastChat == chat2 )
			++m_sameChatRepeatCnt;
		else
			m_sameChatRepeatCnt = 0;
		if( m_sameChatRepeatCnt >= 2 )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_NO_SAME_SENTANCE), 0x0000FF, 0);
			g_windowMgr.UIWindowMgr::ClearChatMsg();
			break;
		}

		m_lastChat = chat2;

		char chat[246+1];
		sprintf(chat, "%s : %s%s", g_session.CSession::GetCharName(), g_language->CLanguage::GetLanguageCharset(), g_windowMgr.UIWindowMgr::GetChatMsg());
		size_t chatlen = strlen(chat);

		g_windowMgr.UIWindowMgr::ClearChatMsg();

		char buf[1024];
		PACKET_CZ_REQUEST_CHAT_PARTY& packet = *(PACKET_CZ_REQUEST_CHAT_PARTY*)buf;
		packet.PacketType = HEADER_CZ_REQUEST_CHAT_PARTY;
		packet.PacketLength = sizeof(packet) + chatlen + 1;
		memcpy(packet.Text, chat, chatlen + 1);
		g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
	}
	break;
	case 73: //MM_BEGIN_DRAG_FROM_SHORTCUTWND
	{
		int itemIndex = (int)val1;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		ITEM_INFO itemInfo = g_session.CSession::GetItemInfoByIndex(itemIndex);
		if( !itemInfo.ITEM_INFO::IsValid() )
			break;

		m_dragInfo.m_dragType = DT_FROM_SHORTCUTWND;
		m_dragInfo.m_numDragItem = itemInfo.m_num;
		m_dragInfo.m_isIdentified = itemInfo.m_isIdentified;
		m_dragInfo.m_dragItemIndex = itemIndex;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(itemInfo.m_itemName.c_str(), itemInfo.m_isIdentified);
		m_dragInfo.m_dragItemName = itemInfo.m_itemName;
		m_dragInfo.m_slotNum = -1;
		m_dragInfo.m_refiningLevel = itemInfo.m_refiningLevel;
		m_dragInfo.m_slot[0] = itemInfo.m_slot[0];
		m_dragInfo.m_slot[1] = itemInfo.m_slot[1];
		m_dragInfo.m_slot[2] = itemInfo.m_slot[2];
		m_dragInfo.m_slot[3] = itemInfo.m_slot[3];
	}
	break;
	case 74: //MM_UPGRADE_SKILLLEVEL
	{
		unsigned short SKID = (unsigned short)val1;

		if( m_isReqUpgradeSkillLevel != 0 )
			break;
		m_isReqUpgradeSkillLevel = 1;

		PACKET_CZ_UPGRADE_SKILLLEVEL packet;
		packet.PacketType = HEADER_CZ_UPGRADE_SKILLLEVEL;
		packet.SKID = SKID;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
//	case 75: //MM_SCREENSHOT
//		//default
//	break;
	case 76: //MM_USE_SKILL
	{
		unsigned short SKID = (unsigned short)val1;
		unsigned long targetID = (unsigned long)val2;
		short level = (short)val3;

		if( SKID == 10000 ) //FIXME: overlaps with SKID_GD_APPROVAL
		{
			if( targetID != g_session.m_petGID )
				g_windowMgr.UIWindowMgr::MakeWindow(WID_PETTAMINGDECEIVEWND)->SendMsg(0, 80, 0, (int)targetID, 0);
			break;
		}

		if( SKID == 20000 )
		{
			PACKET_CZ_REQ_JOIN_COUPLE packet;
			packet.PacketType = HEADER_CZ_REQ_JOIN_COUPLE;
			packet.AID = targetID;
			g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
			break;
		}

		if( SKID == 20001 )
		{
			char msgBuf[256];
			sprintf(msgBuf, "[ (val1 == 20001) ]");
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)msgBuf, 0x6E96FF, 0);

			PACKET_CZ_REQ_JOIN_BABY packet;
			packet.PacketType = HEADER_CZ_REQ_JOIN_BABY;
			packet.AID = targetID;
			g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
			break;
		}

		if( g_windowMgr.UIWindowMgr::GetMerchantItemMyShopWnd() )
			break;

		if( level == 0 )
		{
			SKILL_INFO skillInfo = g_session.CSession::GetSkillItemInfoBySkillId(SKID);
			if( skillInfo.m_isValid )
				level = static_cast<short>(skillInfo.level);
		}
		if( level == 0 )
		{
			SKILL_INFO skillInfo = g_session.CSession::GetTempSkillItemInfoBySkillId(SKID);
			if( skillInfo.m_isValid )
				level = static_cast<short>(skillInfo.level);
		}

		if( m_world->m_player->m_stateId == STATEID_SIT )
			break;

		if( g_windowMgr.UIWindowMgr::GetChatRoomWnd() )
			break;

		if( SKID == SKID_MC_CHANGECART )
		{
			if( g_session.CSession::GetSp() < 40 )
			{
				char msgBuf[256];
				sprintf(msgBuf, MsgStr(MSI_USESKILL_FAIL_SP_INSUFFICIENT));
				g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)msgBuf, 0x0000FF, 0);
				break;
			}

			if( !IsEffectStatePushCart(g_session.m_effectState) )
			{
				char msgBuf[256];
				sprintf(msgBuf, MsgStr(MSI_MUST_EQUIP_CART));
				g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)msgBuf, 0x0000FF, 0);
				break;
			}

			g_windowMgr.UIWindowMgr::MakeWindow(WID_SELECTCARTWND);
		}

		PACKET_CZ_USE_SKILL packet;
		packet.PacketType = HEADER_CZ_USE_SKILL;
		packet.selectedLevel = level;
		packet.SKID = SKID;
		packet.targetID = targetID;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 77: //MM_USE_SKILL_TOGROUND
	{
		struct UNKNOWN_SKILL_STRUCT { int skillId; int xPos; int yPos; int skillLv; };
		UNKNOWN_SKILL_STRUCT& skill = *(UNKNOWN_SKILL_STRUCT*)val1;

		int lv = skill.skillLv;
		if( lv == 0 )
			lv = g_session.CSession::GetSkillItemInfoBySkillId(skill.skillId).level;

		PACKET_CZ_USE_SKILL_TOGROUND packet;
		packet.PacketType = HEADER_CZ_USE_SKILL_TOGROUND;
		packet.selectedLevel = static_cast<short>(lv);
		packet.SKID = static_cast<unsigned short>(skill.skillId);
		packet.xPos = static_cast<short>(skill.xPos);
		packet.yPos = static_cast<short>(skill.yPos);
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 78: //MM_CANCEL_USE_SKILL
		m_skillUseInfo.m_skillUseType = SUT_NOSKILL;
		m_skillUseInfo.m_skillId = 0;
		m_skillUseInfo.m_useLevel = 0;
		g_isGoodSkillHanging = 0;
	break;
	case 79: //MM_HANG_USE_SKILL
	{
		ENUM_SKILL_USE_TYPE skillUseType = (ENUM_SKILL_USE_TYPE)val1;
		SKILL_INFO* skillInfo = (SKILL_INFO*)val2;
		int useLevel = (int)val3;

		if( g_windowMgr.UIWindowMgr::GetMerchantItemMyShopWnd() )
			break;

		m_skillUseInfo.m_skillUseType = skillUseType;

		if( skillInfo == NULL )
			break;

		m_skillUseInfo.m_skillId = skillInfo->SKID;
		m_skillUseInfo.m_attackRange = skillInfo->attackRange;
		if( SKILL_INFO::IsLevelUseSkill(skillInfo->SKID) )
		{
			m_skillUseInfo.m_useLevel = useLevel;
		}
		else
		{
			SKILL_INFO useInfo = g_session.CSession::GetSkillItemInfoBySkillId(m_skillUseInfo.m_skillId);
			m_skillUseInfo.m_useLevel = ( useInfo.m_isValid ) ? useInfo.level : 0;
		}

		g_isGoodSkillHanging = SKILL_INFO::IsGoodSkillForActor(m_skillUseInfo.m_skillId);
	}
	break;
	case 80: //MM_CANCEL_LOCKON
	{
		PACKET_CZ_CANCEL_LOCKON packet;
		packet.PacketType = HEADER_CZ_CANCEL_LOCKON;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 81: //MM_BEGIN_DRAG_FROM_SKILLLISTWND
	{
		int skillIndex = (int)val1;
		const char* skillName = (const char*)val2;
		int skillLevel = (int)val3;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		m_dragInfo.m_dragType = DT_FROM_SKILLLISTWND;
		m_dragInfo.m_dragItemIndex = skillIndex;
		m_dragInfo.m_isIdentified = 0;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName_Skill(skillName);
		m_dragInfo.m_dragItemName = skillName;
		m_dragInfo.m_skillName = skillName;
		m_dragInfo.m_skillUseLevel = skillLevel;
	}
	break;
	case 82: //MM_SELECT_WARPPOINT
	{
		const char* mapName = (const char*)val1;
		unsigned short SKID = (unsigned short)val2;

		PACKET_CZ_SELECT_WARPPOINT packet;
		packet.PacketType = HEADER_CZ_SELECT_WARPPOINT;
		packet.SKID = SKID;
		strncpy(packet.mapName, mapName, sizeof(packet.mapName)); //FIXME: zero terminator
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 83: //MM_REMEMBER_WARPPOINT
	{
		PACKET_CZ_REMEMBER_WARPPOINT packet;
		packet.PacketType = HEADER_CZ_REMEMBER_WARPPOINT;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 84: //MM_MOVE_ITEM_FROM_BODY_TO_CART
	{
		short index = (short)val1;
		int count = (int)val2;

		PACKET_CZ_MOVE_ITEM_FROM_BODY_TO_CART packet;
		packet.PacketType = HEADER_CZ_MOVE_ITEM_FROM_BODY_TO_CART;
		packet.index = index;
		packet.count = count;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 85: //MM_MOVE_ITEM_FROM_CART_TO_BODY
	{
		short index = (short)val1;
		int count = (int)val2;

		PACKET_CZ_MOVE_ITEM_FROM_CART_TO_BODY packet;
		packet.PacketType = HEADER_CZ_MOVE_ITEM_FROM_CART_TO_BODY;
		packet.index = index;
		packet.count = count;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 86: //MM_MOVE_ITEM_FROM_STORE_TO_CART
	{
		short index = (short)val1;
		int count = (int)val2;

		PACKET_CZ_MOVE_ITEM_FROM_STORE_TO_CART packet;
		packet.PacketType = HEADER_CZ_MOVE_ITEM_FROM_STORE_TO_CART;
		packet.index = index;
		packet.count = count;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 87: //MM_MOVE_ITEM_FROM_CART_TO_STORE
	{
		short index = (short)val1;
		int count = (int)val2;

		PACKET_CZ_MOVE_ITEM_FROM_CART_TO_STORE packet;
		packet.PacketType = HEADER_CZ_MOVE_ITEM_FROM_CART_TO_STORE;
		packet.index = index;
		packet.count = count;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 88: //MM_REQ_CARTOFF
	case 145: //MM_REQ_BIRDOFF
	case 146: //MM_REQ_CHIKENOFF
	{
		PACKET_CZ_REQ_CARTOFF packet;
		packet.PacketType = HEADER_CZ_REQ_CARTOFF;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 89: //MM_BEGIN_DRAG_FROM_MERCHANTITEMWND
	{
		int itemIndex = (int)val1;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		ITEM_INFO itemInfo = g_session.CSession::GetMerchantItemInfoByIndex(itemIndex);
		if( !itemInfo.ITEM_INFO::IsValid() )
			break;

		m_dragInfo.m_dragType = DT_FROM_MERCHANTITEMWND;
		m_dragInfo.m_numDragItem = itemInfo.m_num;
		m_dragInfo.m_isIdentified = itemInfo.m_isIdentified;
		m_dragInfo.m_dragItemIndex = itemIndex;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(itemInfo.m_itemName.c_str(), itemInfo.m_isIdentified);
		m_dragInfo.m_dragItemName = itemInfo.m_itemName;
		m_dragInfo.m_slotNum = -1;
		m_dragInfo.m_refiningLevel = itemInfo.m_refiningLevel;
		m_dragInfo.m_slot[0] = itemInfo.m_slot[0];
		m_dragInfo.m_slot[1] = itemInfo.m_slot[1];
		m_dragInfo.m_slot[2] = itemInfo.m_slot[2];
		m_dragInfo.m_slot[3] = itemInfo.m_slot[3];
	}
	break;
	case 90: //MM_REQ_CLOSESTORE
	{
		PACKET_CZ_REQ_CLOSESTORE packet;
		packet.PacketType = HEADER_CZ_REQ_CLOSESTORE;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 91: //MM_REQ_OPENSTORE
	{
		const char* storeName = (const char*)val1;
		int flag = (int)val2;

		int num = g_session.CSession::GetNumMerchantHopeToSellItem();

		char buf[2048];
		PACKET_CZ_REQ_OPENSTORE2& packet = *(PACKET_CZ_REQ_OPENSTORE2*)buf;
		packet.PacketType = HEADER_CZ_REQ_OPENSTORE2;
		packet.PacketLength = sizeof(packet) + num * sizeof(packet.Info[0]);

		if( flag == 1 )
		{
			strncpy(packet.storeName, (const char *)val1, countof(packet.storeName)-1); packet.storeName[countof(packet.storeName)-1] = '\0';
			packet.result = 1;
		}
		else
		{
			packet.storeName[0] = '\0';
			packet.result = 0;
		}

		g_session.m_myShopName = packet.storeName;

		int n = 0;
		for( int i = 0; i < num; ++i )
		{
			ITEM_INFO itemInfo = g_session.CSession::GetMerchantHopeToSellItemInfoBySequence(i);
			if( !itemInfo.ITEM_INFO::IsValid() )
				continue; //FIXME: packet length not adjusted

			Trace("MM_REQ_OPENSTORE itemInfo.m_itemIndex == %d", itemInfo.m_itemIndex);

			PACKET_CZ_REQ_OPENSTORE2::PRODUCTINFO_INSTORE Info;
			Info.index = static_cast<short>(itemInfo.m_itemIndex);
			Info.count = static_cast<short>(itemInfo.m_num);
			Info.price = itemInfo.m_realPrice;

			packet.Info[n] = Info;
			++n;
		}

		if( num == 0 ) //FIXME: should check 'n' instead
			packet.result = 0;

		g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
		g_session.CSession::ClearMerchantHopeToSellItem();
	}
	break;
	case 92: //MM_PC_PURCHASE_ITEMLIST_FROMMC
	{
		unsigned long mcAID = (unsigned long)val1;

		g_session.CSession::CloneMerchantPurchaseItemToMerchantPurchaseItemSaved();
		int numItem = g_session.CSession::GetNumMerchantPurchaseItem();

		char buf[2048];
		PACKET_CZ_PC_PURCHASE_ITEMLIST_FROMMC& packet = *(PACKET_CZ_PC_PURCHASE_ITEMLIST_FROMMC*)buf;
		packet.PacketType = HEADER_CZ_PC_PURCHASE_ITEMLIST_FROMMC;
		packet.PacketLength = sizeof(packet) + numItem * sizeof(packet.Item[0]);
		packet.AID = mcAID;

		if( packet.PacketLength > sizeof(buf) )
			break;

		int n = 0;
		for( int i = 0; i < numItem; ++i )
		{
			ITEM_INFO itemInfo = g_session.CSession::GetMerchantPurchaseItemInfoBySequence(i);
			if( !itemInfo.ITEM_INFO::IsValid() )
				continue; //FIXME: packet length not adjusted

			PACKET_CZ_PC_PURCHASE_ITEMLIST_FROMMC::CZ_PURCHASE_ITEM_FROMMC Item;
			Item.count = static_cast<short>(itemInfo.m_num);
			Item.index = static_cast<short>(itemInfo.m_itemIndex);

			packet.Item[n] = Item;
			++n;
		}

		if( numItem != 0 ) //FIXME: should check 'n' instead
			g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
	}
	break;
	case 93: //MM_BEGIN_DRAG_FROM_MERCHANTMIRRORITEMWND
	{
		int itemIndex = (int)val1;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		ITEM_INFO itemInfo = g_session.CSession::GetMerchantMirrorItemInfoByIndex(itemIndex);
		if( !itemInfo.ITEM_INFO::IsValid() )
			break;

		m_dragInfo.m_dragType = DT_FROM_MERCHANTMIRRORITEMWND;
		m_dragInfo.m_numDragItem = itemInfo.m_num;
		m_dragInfo.m_isIdentified = itemInfo.m_isIdentified;
		m_dragInfo.m_dragItemIndex = itemIndex;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(itemInfo.m_itemName.c_str(), itemInfo.m_isIdentified);
		m_dragInfo.m_dragItemName = itemInfo.m_itemName;
		m_dragInfo.m_slotNum = -1;
		m_dragInfo.m_refiningLevel = itemInfo.m_refiningLevel;
		m_dragInfo.m_slot[0] = itemInfo.m_slot[0];
		m_dragInfo.m_slot[1] = itemInfo.m_slot[1];
		m_dragInfo.m_slot[2] = itemInfo.m_slot[2];
		m_dragInfo.m_slot[3] = itemInfo.m_slot[3];
	}
	break;
	case 94: //MM_BEGIN_DRAG_FROM_MERCHANTSHOPMAKEWND
	{
		int itemIndex = (int)val1;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		ITEM_INFO itemInfo = g_session.CSession::GetMerchantHopeToSellItemInfoByIndex(itemIndex);
		if( !itemInfo.ITEM_INFO::IsValid() )
			break;

		m_dragInfo.m_isIdentified = itemInfo.m_isIdentified;
		m_dragInfo.m_dragType = DT_FROM_MERCHANTSHOPMAKEWND;
		m_dragInfo.m_dragItemIndex = itemIndex;
		m_dragInfo.m_numDragItem = itemInfo.m_num;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(itemInfo.m_itemName.c_str(), itemInfo.m_isIdentified);
		m_dragInfo.m_dragItemName = itemInfo.m_itemName;
		m_dragInfo.m_slotNum = -1;
		m_dragInfo.m_refiningLevel = itemInfo.m_refiningLevel;
		m_dragInfo.m_slot[0] = itemInfo.m_slot[0];
		m_dragInfo.m_slot[1] = itemInfo.m_slot[1];
		m_dragInfo.m_slot[2] = itemInfo.m_slot[2];
		m_dragInfo.m_slot[3] = itemInfo.m_slot[3];
	}
	break;
	case 95: //MM_REQ_BUY_FROMMC
	{
		unsigned long AID = (unsigned long)val1;

		if( AID == g_session.CSession::GetAid() || g_windowMgr.UIWindowMgr::GetMerchantItemShopWnd() != NULL || timeGetTime() <= m_reqTickMerchantShop + 1000 )
			break;

		m_reqTickMerchantShop = timeGetTime();

		PACKET_CZ_REQ_BUY_FROMMC packet;
		packet.PacketType = HEADER_CZ_REQ_BUY_FROMMC;
		packet.AID = AID;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 96: //MM_BEGIN_DRAG_FROM_MERCHANTITEMSHOPWND
	{
		ITEM_INFO& itemInfo = *(ITEM_INFO*)val1;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		if( !itemInfo.ITEM_INFO::IsValid() )
			break;

		m_dragInfo.m_dragType = DT_FROM_MERCHANTITEMSHOPWND;
		m_dragInfo.m_dragItemIndex = itemInfo.m_itemIndex;
		m_dragInfo.m_numDragItem = 1;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(itemInfo.m_itemName.c_str(), itemInfo.m_isIdentified);
		m_dragInfo.m_dragItemName = itemInfo.m_itemName;
		m_dragInfo.m_dragItemPrice = itemInfo.m_price;
		m_dragInfo.m_dragItemRealPrice = itemInfo.m_realPrice;
		m_dragInfo.m_dragItemType = itemInfo.m_itemType;
		m_dragInfo.m_isIdentified = itemInfo.m_isIdentified;
		m_dragInfo.m_slotNum = -1;
		m_dragInfo.m_refiningLevel = itemInfo.m_refiningLevel;
		m_dragInfo.m_slot[0] = itemInfo.m_slot[0];
		m_dragInfo.m_slot[1] = itemInfo.m_slot[1];
		m_dragInfo.m_slot[2] = itemInfo.m_slot[2];
		m_dragInfo.m_slot[3] = itemInfo.m_slot[3];
	}
	break;
	case 97: //MM_BEGIN_DRAG_FROM_MERCHANTITEMPURCHASEWND
	{
		const char* itemName = (const char*)val1;

		g_windowMgr.UIWindowMgr::ShowWindow(WID_ITEMDROPCNTWND, 0);
		this->CGameMode::ResetDrag();

		ITEM_INFO itemInfo = g_session.CSession::GetMerchantPurchaseItemInfoByName(itemName);
		if( itemInfo.m_itemIndex == 0 )
			break;

		m_dragInfo.m_dragItemIndex = itemInfo.m_itemIndex;
		m_dragInfo.m_isIdentified = itemInfo.m_isIdentified;
		m_dragInfo.m_dragType = DT_FROM_MERCHANTITEMPURCHASEWND;
		m_dragInfo.m_numDragItem = itemInfo.m_num;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(itemName, itemInfo.m_isIdentified);
		m_dragInfo.m_dragItemName = itemName;
		m_dragInfo.m_dragItemPrice = itemInfo.m_price;
		m_dragInfo.m_dragItemRealPrice = itemInfo.m_realPrice;
		m_dragInfo.m_numDragItem = itemInfo.m_num;
		m_dragInfo.m_slotNum = -1;
		m_dragInfo.m_refiningLevel = itemInfo.m_refiningLevel;
		m_dragInfo.m_slot[0] = itemInfo.m_slot[0];
		m_dragInfo.m_slot[1] = itemInfo.m_slot[1];
		m_dragInfo.m_slot[2] = itemInfo.m_slot[2];
		m_dragInfo.m_slot[3] = itemInfo.m_slot[3];
	}
	break;
	case 98: //MM_PKMODE_CHANGE
	break;
	case 99: //MM_MAKE_SKILL_USED_MSG
	{
		int SKID = (int)val1;
		CGameActor* actor = (CGameActor*)val2;
		int level_or_aid = (int)val3;

		m_skillUsedTick = timeGetTime();

		if( actor == NULL || level_or_aid < 0 || SKID < 0 )
			break;

		switch( SKID )
		{
		case SKID_WE_MALE:
		case SKID_WE_FEMALE:
		{
			unsigned long AID = (unsigned long)level_or_aid;
			NamePair name = g_modeMgr.CModeMgr::GetGameMode()->CGameMode::GetActorName(AID);

			char skillName[64];
			strcpy(skillName, SKILL_INFO::GetSkillNameBySkillId(SKID));
			strcat(skillName, " ♡");

			char charName[64];
			strcpy(charName, name.cName.c_str());
			strcat(charName, " !!  ");
			strcat(charName, MsgStr(MSI_LOVE_SKILL));

			actor->SendMsg(NULL, 7, (int)charName, 0, 0);
		}
		break;
		case SKID_WE_CALLPARTNER:
		{
			char skillName[64];
			strcpy(skillName, SKILL_INFO::GetSkillNameBySkillId(SKID));
			strcat(skillName, " ♡");

			char charName[64];
			memcpy(charName, m_CoupleName, 24);
			strcat(charName, " !!  ");
			strcat(charName, skillName);

			actor->SendMsg(NULL, 7, (int)charName, 0, 0);
		}
		break;
		case SKID_DC_SCREAM:
		case SKID_BA_FROSTJOKER:
			;
		break;
		default:
		{
			char skillName[64];
			strcpy(skillName, SKILL_INFO::GetSkillNameBySkillId(SKID));
			strcat(skillName, " !!");

			actor->SendMsg(NULL, 7, (int)skillName, 0, 0);
		}
		break;
		};
	}
	break;
	case 100: //MM_WEAR_EQUIP_ARROW
	{
		unsigned short index = (unsigned short)val1;
		unsigned short wearLocation = (unsigned short)val2;

		Trace("MM_WEAR_EQUIP_ARROW1");
		if( m_waitingWearEquipAck + 2000 > timeGetTime() || m_isPlayerDead )
			break;
		Trace("MM_WEAR_EQUIP_ARROW2");

		m_waitingWearEquipAck = timeGetTime();

		PACKET_CZ_REQ_WEAR_EQUIP packet;
		packet.PacketType = HEADER_CZ_REQ_WEAR_EQUIP;
		packet.index = index;
		packet.wearLocation = wearLocation;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 101: //MM_QUIT_GAME
		this->SendMsg(MM_REQ_DISCONNECT, 0, 0, 0);
	break;
	case 102: //MM_CLOSE_DIALOG
	{
		unsigned long npcaid = (unsigned long)val1;

		m_isOnQuest = 0;
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_SAYDIALOGWND);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_CHOOSEWND);

		PACKET_CZ_CLOSE_DIALOG packet;
		packet.PacketType = HEADER_CZ_CLOSE_DIALOG;
		packet.NAID = npcaid;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 103: //MM_REFRESH_MUSIC
	{
		if( g_session.m_bgmIsPaused )
			CloseStream();
		else
			PlayStream(m_streamFileName.c_str());
	}
	break;
	case 104: //MM_ITEM_CREATE
	{
		const char* itemName = (const char*)val1;

		PACKET_CZ_ITEM_CREATE packet;
		packet.PacketType = HEADER_CZ_ITEM_CREATE;
		strncpy(packet.itemName, itemName, sizeof(packet.itemName)); //FIXME: zero terminator
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 105: //MM_MOVETO_MAP
	{
		const char* mapName = (const char*)val1;
		short xPos = (short)val2;
		short yPos = (short)val3;

		PACKET_CZ_MOVETO_MAP packet;
		packet.PacketType = HEADER_CZ_MOVETO_MAP;
		strncpy(packet.mapName, mapName, sizeof(packet.mapName)); //FIXME: zero terminator
		packet.xPos = xPos;
		packet.yPos = yPos;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 106: //MM_USESKILL_LEVEL_PLUS
	{
		int plusValue = (int)val1;

		if( SKILL_INFO::IsLevelUseSkill(m_skillUseInfo.m_skillId) == 0 )
			break;

		SKILL_INFO skillInfo = g_session.CSession::GetSkillItemInfoBySkillId(m_skillUseInfo.m_skillId);
		if( !skillInfo.m_isValid )
			break;

		m_skillUseInfo.m_useLevel += plusValue;

		if( m_skillUseInfo.m_useLevel > skillInfo.level )
			m_skillUseInfo.m_useLevel = skillInfo.level;

		if( m_skillUseInfo.m_useLevel < 1 )
			m_skillUseInfo.m_useLevel = 1;
	}
	break;
	case 107: //MM_USESKILL_LEVEL_MINUS
	{
		int minusValue = (int)val1;

		if( SKILL_INFO::IsLevelUseSkill(m_skillUseInfo.m_skillId) == 0 )
			break;

		SKILL_INFO skillInfo = g_session.CSession::GetSkillItemInfoBySkillId(m_skillUseInfo.m_skillId);
		if( !skillInfo.m_isValid )
			break;

		m_skillUseInfo.m_useLevel -= minusValue;

		if( m_skillUseInfo.m_useLevel > skillInfo.level )
			m_skillUseInfo.m_useLevel = skillInfo.level;

		if( m_skillUseInfo.m_useLevel < 1 )
			m_skillUseInfo.m_useLevel = 1;
	}
	break;
	case 108: //MM_GET_SKILL_USE_TYPE
		return m_skillUseInfo.m_skillUseType;
	break;
	case 109: //MM_CHANGE_GROUPEXPOPTION
	{
		unsigned long expOption = (unsigned long)val1;

		PACKET_CZ_CHANGE_GROUPEXPOPTION packet;
		packet.PacketType = HEADER_CZ_CHANGE_GROUPEXPOPTION;
		packet.expOption = expOption;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 110: //MM_GET_SKILL_USE_LEVEL
		return m_skillUseInfo.m_useLevel;
	break;
	case 111: //MM_CHANGE_SKILL_NAME
	break;
	case 112: //MM_SEND_NUMBER_TO_NPC
	{
		unsigned long npcAID = (unsigned long)val1;
		int value = (int)val2;

		if( m_world->CWorld::GetGameActorByAID(npcAID) == NULL )
			break;

		PACKET_CZ_INPUT_EDITDLG packet;
		packet.PacketType = HEADER_CZ_INPUT_EDITDLG;
		packet.NAID = npcAID;
		packet.value = value;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 113: //MM_SHOW_IMAGE
	{
		const char* imgname = (const char*)val1;
		int showtype = (int)val2;

		m_showImageInfo.type = showtype;
		m_showImageInfo.imageName = imgname;
		if( m_showImageInfo.imageName.find(".bmp", 0, strlen(".bmp")) == -1
		 && m_showImageInfo.imageName.find(".BMP", 0, strlen(".BMP")) == -1 )
			m_showImageInfo.imageName.append(".bmp", strlen(".bmp"));
	}
	break;
	case 114: //MM_INITWHISPERMENU
	{
		const char* initName = (const char*)val1;

		m_lastWhisperMenuCharacterName = initName;

		m_menuIdList.clear();
		m_menuIdList.push_back(11);
		m_menuIdList.push_back(21);
	}
	break;
	case 115: //MM_SEND_GUILD_EMBLEM
	{
		const char* emblemData = (const char*)val1;
		int emblemSize = (int)val2;

		if( !g_guildInfo.m_amIMaster )
			break;

		char buf[2048];
		PACKET_CZ_REGISTER_GUILD_EMBLEM_IMG& packet = *(PACKET_CZ_REGISTER_GUILD_EMBLEM_IMG*)buf;
		packet.PacketType = HEADER_CZ_REGISTER_GUILD_EMBLEM_IMG;
		packet.PacketLength = sizeof(packet) + emblemSize;

		if( packet.PacketLength > sizeof(buf) )
			break;

		memcpy(packet.Emblem, emblemData, emblemSize);
		g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
	}
	break;
	case 116: //MM_REQ_CHANGE_MEMBERPOS
	{
		if( !g_guildInfo.m_amIMaster )
			break;

		char buf[2048];
		PACKET_CZ_REQ_CHANGE_MEMBERPOS& packet = *(PACKET_CZ_REQ_CHANGE_MEMBERPOS*)buf;
		packet.PacketType = HEADER_CZ_REQ_CHANGE_MEMBERPOS;
		packet.PacketLength = sizeof(packet) + g_guildInfo.m_memberPositionInfoListForChange.size() * sizeof(packet.Info[0]);

		if( packet.PacketLength > sizeof(buf) )
			break;

		int n = 0;
		for( mystd::map<int,MEMBER_POSITION_INFORMATION>::const_iterator it = g_guildInfo.m_memberPositionInfoListForChange.begin(); it != g_guildInfo.m_memberPositionInfoListForChange.end(); ++it )
		{
			MEMBER_POSITION_INFORMATION Info;
			Info.AID = it->second.AID;
			Info.GID = it->second.GID;
			Info.positionID = it->second.positionID;

			packet.Info[n] = Info;
			++n;
		}

		g_guildInfo.m_memberPositionInfoListForChange.clear();
		g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
	}
	break;
	case 117: //MM_REQ_CHANGE_GUILD_POSITIONINFO
	{
		if( !g_guildInfo.m_amIMaster )
			break;

		char buf[2048];
		PACKET_CZ_REG_CHANGE_GUILD_POSITIONINFO& packet = *(PACKET_CZ_REG_CHANGE_GUILD_POSITIONINFO*)buf;
		packet.PacketType = HEADER_CZ_REG_CHANGE_GUILD_POSITIONINFO;
		packet.PacketLength = sizeof(packet) + g_guildInfo.m_changedPositionInfoList.size() * sizeof(packet.Info[0]);

		if( packet.PacketLength > sizeof(buf) )
			break;

		int n = 0;
		for( mystd::map<int,GUILD_POSITION_INFORMATION>::iterator it = g_guildInfo.m_changedPositionInfoList.begin(); it != g_guildInfo.m_changedPositionInfoList.end(); ++it )
		{
			PACKET_CZ_REG_CHANGE_GUILD_POSITIONINFO::GUILD_REG_POSITION_INFO Info;
			Info.positionID = it->second.positionID;
			Info.right = 0;
			if( it->second.rightOfJoin ) Info.right |= 0x01;
			if( it->second.rightOfPunish ) Info.right |= 0x10;
			Info.ranking = it->second.ranking;
			Info.payRate = it->second.payRate;
			strncpy(Info.posName, it->second.posName.c_str(), sizeof(Info.posName)-1); Info.posName[sizeof(Info.posName)-1] = '\0';

			packet.Info[n] = Info;
			++n;
		}

		g_guildInfo.m_changedPositionInfoList.clear();
		g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
	}
	break;
	case 118: //MM_REQ_GUILD_MENUINTERFACE
	{
		PACKET_CZ_REQ_GUILD_MENUINTERFACE packet;
		packet.PacketType = HEADER_CZ_REQ_GUILD_MENUINTERFACE;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 119: //MM_REQ_DISORGANIZE_GUILD
	{
		const char* key = (const char*)val1;

		if( !g_guildInfo.m_amIMaster )
			break;

		PACKET_CZ_REQ_DISORGANIZE_GUILD packet;
		packet.PacketType = HEADER_CZ_REQ_DISORGANIZE_GUILD;
		strncpy(packet.key, key, sizeof(packet.key)-1); packet.key[sizeof(packet.key)-1] = '\0';
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 120: //MM_REQ_GUILD_MENU
	{
		int Type = (int)val1;

		PACKET_CZ_REQ_GUILD_MENU packet;
		packet.PacketType = HEADER_CZ_REQ_GUILD_MENU;
		packet.Type = Type;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 121: //MM_REQ_GUILD_EMBLEM_IMG
	{
		unsigned long GDID = (unsigned long)val1;

		if( GDID == 0 )
			break;

		mystd::list<unsigned long>::iterator it = m_emblemReqGdidQueue.begin();
		while( it != m_emblemReqGdidQueue.end() )
		{
			if( *it == GDID )
				it = m_emblemReqGdidQueue.erase(it);
			else
				++it;
		}

		if( !g_session.CSession::GetEmblemState() )
			break;

		PACKET_CZ_REQ_GUILD_EMBLEM_IMG packet;
		packet.PacketType = HEADER_CZ_REQ_GUILD_EMBLEM_IMG;
		packet.GDID = GDID;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 122: //MM_REQ_OPEN_MEMBER_INFO
	{
		int AID = (int)val1;

		PACKET_CZ_REQ_OPEN_MEMBER_INFO packet;
		packet.PacketType = HEADER_CZ_REQ_OPEN_MEMBER_INFO;
		packet.AID = AID;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 123: //MM_REQ_LEAVE_GUILD
	{
		const char* reasonDesc = (const char*)val1;

		PACKET_CZ_REQ_LEAVE_GUILD packet;
		packet.PacketType = HEADER_CZ_REQ_LEAVE_GUILD;
		packet.GDID = g_guildInfo.m_gdid;
		packet.AID = g_session.CSession::GetAid();
		packet.GID = g_session.CSession::GetGid();
		strncpy(packet.reasonDesc, reasonDesc, sizeof(packet.reasonDesc)-1); packet.reasonDesc[sizeof(packet.reasonDesc)-1] = '\0';
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 124: //MM_REQ_BAN_GUILD
	{
		struct UIGUILDBANREASONDESCWND_VARS { unsigned long GDID; int AID; int GID; };
		UIGUILDBANREASONDESCWND_VARS& memberInfo = *(UIGUILDBANREASONDESCWND_VARS*)val1;
		const char* reasonDesc = (const char*)val2;

		if( !g_guildInfo.m_amIMaster )
			break;

		PACKET_CZ_REQ_BAN_GUILD packet;
		packet.PacketType = HEADER_CZ_REQ_BAN_GUILD;
		packet.GDID = memberInfo.GDID;
		packet.AID = memberInfo.AID;
		packet.GID = memberInfo.GID;
		strncpy(packet.reasonDesc, reasonDesc, sizeof(packet.reasonDesc)-1); packet.reasonDesc[sizeof(packet.reasonDesc)-1] = '\0';
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 125: //MM_REQ_MAKE_GUILD
	{
		const char* GName = (const char*)val1;

		if( strlen(GName) >= 24 )
		{
			g_windowMgr.UIWindowMgr::ErrorMsg(MsgStr(MSI_NAMELENGTH_TOO_LONG), 0, 1, 0, 0);
			break;
		}

		PACKET_CZ_REQ_MAKE_GUILD packet;
		packet.PacketType = HEADER_CZ_REQ_MAKE_GUILD;
		packet.GID = g_session.CSession::GetGid();
		strncpy(packet.GName, GName, sizeof(packet.GName)-1); packet.GName[sizeof(packet.GName)-1] = '\0';
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 126: //MM_USING_SKILL
	{
		SKILL_INFO* info = (SKILL_INFO*)val1;
		int level = (int)val2;

		switch( info->type )
		{
		case 0x01: this->SendMsg(MM_HANG_USE_SKILL, SUT_TO_CHARACTER, (int)info, level); break;
		case 0x02: this->SendMsg(MM_HANG_USE_SKILL, SUT_TO_GROUND, (int)info, level); break;
		case 0x04: this->SendMsg(MM_USE_SKILL, info->SKID, g_session.CSession::GetAid(), level); this->SendMsg(MM_HANG_USE_SKILL, SUT_NOSKILL, 0, 0); break;
		case 0x08: this->SendMsg(MM_HANG_USE_SKILL, SUT_TO_ITEM, (int)info, level); break;
		case 0x10: this->SendMsg(MM_HANG_USE_SKILL, SUT_TO_ALL, (int)info, level); break;
		case 0x20: this->SendMsg(MM_HANG_USE_SKILL, SUT_TO_SKILL, (int)info, level); break;
		default: break;
		};
	}
	break;
	case 127: //MM_JOIN_GUILD
	{
		unsigned long GDID = (unsigned long)val1;
		int answer = (int)val2;

		PACKET_CZ_JOIN_GUILD packet;
		packet.PacketType = HEADER_CZ_JOIN_GUILD;
		packet.GDID = GDID;
		packet.answer = answer;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 128: //MM_REQ_JOIN_GUILD
	{
		unsigned long AID = (unsigned long)val1;

		PACKET_CZ_REQ_JOIN_GUILD packet;
		packet.PacketType = HEADER_CZ_REQ_JOIN_GUILD;
		packet.AID = AID;
		packet.MyAID = g_session.CSession::GetAid();
		packet.MyGID = g_session.CSession::GetGid();
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 129: //MM_TESTPACKET
	{
		PACKET_CZ_REQUEST_CHAT packet;
		packet.PacketType = HEADER_CZ_REQUEST_CHAT;
		packet.PacketLength = 2; // !?
		g_connection.CRagConnection::SendPacket(sizeof(packet), (char*)&packet);
	}
	break;
	case 130: //MM_REQ_GIVE_MANNER_POINT
	{
		unsigned long otherAID = (int)val1;
		unsigned char type = (int)val2;
		short point = (int)val3;

		PACKET_CZ_REQ_GIVE_MANNER_POINT packet;
		packet.PacketType = HEADER_CZ_REQ_GIVE_MANNER_POINT;
		packet.otherAID = otherAID;
		packet.type = type;
		packet.point = ( point < 0 ) ? 0 : ( point >= 30000 ) ? 30000 : point;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 131: //MM_GUILD_NOTICE
	{
		unsigned long GDID = (unsigned long)val1;
		const char* subject = (const char*)val2;
		const char* notice = (const char*)val3;

		PACKET_CZ_GUILD_NOTICE packet;
		packet.PacketType = HEADER_CZ_GUILD_NOTICE;
		packet.GDID = GDID;
		strncpy(packet.subject, subject, sizeof(packet.subject)-1); packet.subject[sizeof(packet.subject)-1] = '\0';
		strncpy(packet.notice, notice, sizeof(packet.notice)-1); packet.notice[sizeof(packet.notice)-1] = '\0';
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 132: //MM_REQ_ALLY_GUILD
	{
		unsigned long AID = (unsigned long)val1;

		PACKET_CZ_REQ_ALLY_GUILD packet;
		packet.PacketType = HEADER_CZ_REQ_ALLY_GUILD;
		packet.AID = AID;
		packet.MyAID = g_session.CSession::GetAid();
		packet.MyGID = g_session.CSession::GetGid();
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 133: //MM_ALLY_GUILD
	{
		unsigned long otherAID = (unsigned long)val1;
		int answer = (int)val2;

		PACKET_CZ_ALLY_GUILD packet;
		packet.PacketType = HEADER_CZ_ALLY_GUILD;
		packet.otherAID = otherAID;
		packet.answer = answer;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 134: //MM_REQ_ITEMIDENTIFY
	{
		short index = (short)val1;

		PACKET_CZ_REQ_ITEMIDENTIFY packet;
		packet.PacketType = HEADER_CZ_REQ_ITEMIDENTIFY;
		packet.index = index;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 135: //MM_QUAKE
	{
		int flag = (int)val1;

		if( flag == 1 )
			m_view->CView::SetQuake(TRUE, 1, 1.0f, 0.24f, 0.2f);
		else
			m_view->CView::SetQuake(TRUE, 0, 1.0f, 0.24f, 0.2f);
	}
	break;
	case 136: //MM_REQ_ITEMCOMPOSITION_LIST
	{
		int cardIndex = (int)val1;

		m_lastCardItemIndex = cardIndex;

		PACKET_CZ_REQ_ITEMCOMPOSITION_LIST packet;
		packet.PacketType = HEADER_CZ_REQ_ITEMCOMPOSITION_LIST;
		packet.cardIndex = static_cast<short>(cardIndex);
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 137: //MM_REQ_ITEMCOMPOSITION
	{
		short equipIndex = (short)val1;
		short cardIndex = (short)val2;

		PACKET_CZ_REQ_ITEMCOMPOSITION packet;
		packet.PacketType = HEADER_CZ_REQ_ITEMCOMPOSITION;
		packet.cardIndex = cardIndex;
		packet.equipIndex = equipIndex;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 138: //MM_REQ_HOSTILE_GUILD
	{
		unsigned long AID = (unsigned long)val1;

		PACKET_CZ_REQ_HOSTILE_GUILD packet;
		packet.PacketType = HEADER_CZ_REQ_HOSTILE_GUILD;
		packet.AID = AID;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 139: //MM_QUEUE_REQ_GUILD_EMBLEM_IMG
	{
		unsigned long GDID = (unsigned long)val1;

		m_emblemReqGdidQueue.push_back(GDID);
	}
	break;
	case 140: //MM_REQ_DELETE_RELATED_GUILD
	{
		unsigned long OpponentGDID = (unsigned long)val1;
		int Relation = (int)val2;

		PACKET_CZ_REQ_DELETE_RELATED_GUILD packet;
		packet.PacketType = HEADER_CZ_REQ_DELETE_RELATED_GUILD;
		packet.OpponentGDID = OpponentGDID;
		packet.Relation = Relation;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 141: //MM_REQ_DISCONNECT
	{
		PACKET_CZ_REQ_DISCONNECT packet;
		packet.PacketType = HEADER_CZ_REQ_DISCONNECT;
		packet.type = 0;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 142: //MM_CHAT_GUILD
	{
		if( strlen(g_windowMgr.UIWindowMgr::GetChatMsg()) == 0 || g_guildInfo.m_gdid == 0 || g_session.CSession::IsEFST_Berserk() == 1 )
			break;

		char chat2[246+1];
		strcpy(chat2, g_windowMgr.UIWindowMgr::GetChatMsg());

		if( g_insultFilter.CInsultFilter::IsBadSentence(chat2) )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_NO_SEND_BECAUSE_INSULT), 0x0000FF, 0);
			g_windowMgr.UIWindowMgr::ClearChatMsg();
			break;
		}

		if( m_lastChat == chat2 )
			++m_sameChatRepeatCnt;
		else
			m_sameChatRepeatCnt = 0;
		if( m_sameChatRepeatCnt >= 2 )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_NO_SAME_SENTANCE), 0x0000FF, 0);
			g_windowMgr.UIWindowMgr::ClearChatMsg();
			break;
		}

		m_lastChat = chat2;

		char chat[246+1];
		sprintf(chat, "%s : %s", g_session.CSession::GetCharName(), g_windowMgr.UIWindowMgr::GetChatMsg());
		size_t chatLen = strlen(chat);

		g_windowMgr.UIWindowMgr::ClearChatMsg();

		char buf[1024];
		PACKET_CZ_GUILD_CHAT& packet = *(PACKET_CZ_GUILD_CHAT*)buf;
		packet.PacketType = HEADER_CZ_GUILD_CHAT;
		packet.PacketLength = sizeof(packet) + chatLen + 1;

		if( packet.PacketLength >= sizeof(buf) )
			break;

		memcpy(packet.Text, chat, chatLen + 1);
		g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
	}
	break;
	case 143: //MM_REQ_MAKING_ITEM
	{
		unsigned short ITID = (unsigned short)val1;
		ITEM_INFO(& itemInfo)[3] = *(ITEM_INFO(*)[3])val2;

		PACKET_CZ_REQMAKINGITEM packet;
		packet.PacketType = HEADER_CZ_REQMAKINGITEM;
		packet.info.ITID = ITID;
		packet.info.material_ID[0] = itemInfo[0].ITEM_INFO::GetItemId();
		packet.info.material_ID[1] = itemInfo[1].ITEM_INFO::GetItemId();
		packet.info.material_ID[2] = itemInfo[2].ITEM_INFO::GetItemId();
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 144: //MM_USE_SKILL_TOGROUND_WITH_TALKBOX
	{
		struct UITALKBOXTRAPINPUTWND_VALUES { int skillId; int gSkillDx; int gSkillDy; int skillUseLevel; const char* talkText; };
		UITALKBOXTRAPINPUTWND_VALUES& skillInfo = *(UITALKBOXTRAPINPUTWND_VALUES*)val1;

		PACKET_CZ_USE_SKILL_TOGROUND_WITHTALKBOX packet;
		packet.PacketType = HEADER_CZ_USE_SKILL_TOGROUND_WITHTALKBOX;
		packet.selectedLevel = static_cast<short>(skillInfo.skillUseLevel);
		packet.SKID = static_cast<unsigned short>(skillInfo.skillId);
		packet.xPos = static_cast<short>(skillInfo.gSkillDx);
		packet.yPos = static_cast<short>(skillInfo.gSkillDy);
		strcpy(packet.contents, skillInfo.talkText);

		if( g_insultFilter.CInsultFilter::IsBadSentence(packet.contents) )
		{
			g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_NO_SEND_BECAUSE_INSULT), 0x0000FF, 0);
			break;
		}

		if( packet.selectedLevel == 0 )
			packet.selectedLevel = g_session.CSession::GetSkillItemInfoBySkillId(packet.SKID).level;

		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
//	case 145: //MM_REQ_BIRDOFF
//	case 146: //MM_REQ_CHIKENOFF
		///@see case 88: //MM_REQ_CARTOFF
//	break;
	case 147: //MM_BEGIN_DRAG_FROM_METALPROCESSWND
	{
		const char* itemName = (const char*)val1;

		this->CGameMode::ResetDrag();
		m_dragInfo.m_dragType = DT_FROM_METALPROCESSWND;
		m_dragInfo.m_dragItemName = itemName;
		m_dragInfo.m_dragSprName = g_session.CSession::GetItemSpriteFileName(itemName, TRUE);
	}
	break;
	case 148: //MM_SETQUAKEINFO
	{
		float sideQuake = *(float*)val1;
		float frontQuake = *(float*)val2;
		float latitudeQuake = *(float*)val3;

		m_view->CView::SetQuakeInfo(sideQuake, frontQuake, latitudeQuake);
	}
	break;
	case 149: //MM_ITEMPICKUP
	{
		unsigned long itemAID = (unsigned long)val1;

		PACKET_CZ_ITEM_PICKUP packet;
		packet.PacketType = HEADER_CZ_ITEM_PICKUP;
		packet.ITAID = itemAID;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 150: //MM_REQUEST_ACT
	{
		unsigned char action = (unsigned char)val1;
		unsigned long targetGID = (unsigned long)val2;

		PACKET_CZ_REQUEST_ACT packet;
		packet.PacketType = HEADER_CZ_REQUEST_ACT;
		packet.targetGID = targetGID;
		packet.action = action;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 151: //MM_REQUEST_MOVE
	{
		int srcx = (int)val1;
		int srcy = (int)val2;

		PACKET_CZ_REQUEST_MOVE packet;
		packet.PacketType = HEADER_CZ_REQUEST_MOVE;
		EncodePosDir(srcx, srcy, 0, packet.dest);
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 152: //MM_CHANGE_DIRECTION
	{
		unsigned char dir = (unsigned char)val1;
		short headDir = (short)val2;

		PACKET_CZ_CHANGE_DIRECTION packet;
		packet.PacketType = HEADER_CZ_CHANGE_DIRECTION;
		packet.headDir = headDir;
		packet.dir = dir;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 153: //MM_GUILD_MEMBER_STATUS_CHANGE
	{
		const char* name = (const char*)val1;
		int flag = (int)val2;

		if( flag == 0 )
		{
			char msg[128];
			sprintf(msg, MsgStr(MSI_GUILD_MEMBER_STATUS_OFFLINE), name);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)msg, 0xFFFF00, 0);
		}
		else
		if( flag == 1 )
		{
			char msg[128];
			sprintf(msg, MsgStr(MSI_GUILD_MEMBER_STATUS_ONLINE), name);
			g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)msg, 0xFFFF00, 0);
		}
	}
	break;
	case 154: //MM_QUIT_TO_IDENTRY
		g_mustPumpOutReceiveQueue = FALSE;
		g_loginStartMode = 3;
		g_modeMgr.CModeMgr::Switch(0, "login.rsw");
	break;
	case 155: //MM_RESET_PARAMETER
	{
		int type = (int)val1;

		PACKET_CZ_RESET packet;
		packet.PacketType = HEADER_CZ_RESET;
		packet.type = ( type == 1 ) ? 1 : 0;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 156: //MM_REQ_CHANGE_MAPTYPE
	{
		short xPos = (short)val1;
		short yPos = (short)val2;
		int type = (int)val3;

		PACKET_CZ_CHANGE_MAPTYPE packet;
		packet.PacketType = HEADER_CZ_CHANGE_MAPTYPE;
		packet.xPos = xPos;
		packet.yPos = yPos;
		packet.type = ( type != 0 ) ? 1 : 0;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 157: //MM_CHANGE_EFFECTSTATE
	{
		int effectState = (int)val1;

		PACKET_CZ_CHANGE_EFFECTSTATE packet;
		packet.PacketType = HEADER_CZ_CHANGE_EFFECTSTATE;
		packet.EffectState = effectState;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 158: //MM_PET_RENAME
	{
		const char* newname = (const char*)val1;
		size_t namelen = strlen(newname);

		PACKET_CZ_RENAME_PET packet;
		packet.PacketType = HEADER_CZ_RENAME_PET;
		if( namelen >= sizeof(packet.szName) )
		{
			memcpy(packet.szName, newname, sizeof(packet.szName)); packet.szName[sizeof(packet.szName)-1] = '\0';
		}
		else
		{
			memcpy(packet.szName, newname, namelen + 1);
		}
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 159: //MM_PETEGG_SELECT_FROM_LIST
	{
		short index = (short)val1;

		PACKET_CZ_SELECT_PETEGG packet;
		packet.PacketType = HEADER_CZ_SELECT_PETEGG;
		packet.index = index;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 160: //MM_REQ_PETEGG_INFO
	{
		short index = (short)val1;

		PACKET_CZ_PETEGG_INFO packet;
		packet.PacketType = HEADER_CZ_PETEGG_INFO;
		packet.index = index;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 161: //MM_PET_ACT
	{
		int data = (int)val1;

		if( data != -1 && data < 50000 && g_session.m_petFriendly / 10 >= 90 && g_session.CSession::IsMasterAid(3) != 0 )
		{
			PACKET_CZ_PET_ACT packet;
			packet.PacketType = HEADER_CZ_PET_ACT;
			packet.data = data;
			g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
		}
	}
	break;
	case 162: //MM_PETDECEIVE_SHOOT
	{
		unsigned long targetAID = (unsigned long)val1;

		PACKET_CZ_TRYCAPTURE_MONSTER packet;
		packet.PacketType = HEADER_CZ_TRYCAPTURE_MONSTER;
		packet.targetAID = targetAID;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 163: //MM_COMMAND_PET
	{
		char cSub = (char)val1;

		PACKET_CZ_COMMAND_PET packet;
		packet.PacketType = HEADER_CZ_COMMAND_PET;
		packet.cSub = cSub;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 164: //MM_REQ_GIVE_MANNER_POINT_PLUS
	{
		int mannerPoint = (int)val1;

		this->SendMsg(MM_REQ_GIVE_MANNER_POINT, m_menuTargetAID, 0, mannerPoint);
		g_session.CSession::EraseProhibit(m_menuTargetAID, mannerPoint);
	}
	break;
	case 165: //MM_REQ_GIVE_MANNER_POINT_MINUS
	{
		int mannerPoint = (int)val1;

		this->SendMsg(MM_REQ_GIVE_MANNER_POINT, m_menuTargetAID, 1, mannerPoint);
		g_session.CSession::AppendProhibit(m_menuTargetAID, mannerPoint);
	}
	break;
	case 166: //MM_ARROW_FROM_LIST
	{
		unsigned short id = (unsigned short)val1;

		PACKET_CZ_REQ_MAKINGARROW packet;
		packet.packetType = HEADER_CZ_REQ_MAKINGARROW;
		packet.id = id;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.packetType), (char*)&packet);
	}
	break;
	case 167: //MM_SELECT_CART
	{
		short num = (short)val1;

		PACKET_CZ_REQ_CHANGECART packet;
		packet.packetType = HEADER_CZ_REQ_CHANGECART;
		packet.num = num;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.packetType), (char*)&packet);
	}
	break;
//	case 168: //MM_GUILD_MONEY
//		//default (unused?)
//	break;
	case 169: //MM_REMOVE_TO_AID
	{
		const char* accname = (const char*)val1;

		PACKET_CZ_REMOVE_AID packet;
		packet.PacketType = HEADER_CZ_REMOVE_AID;
		memset(packet.AccountName, 0, sizeof(packet.AccountName));
		strcpy(packet.AccountName, accname);
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 170: //MM_SHIFT_TO_GID
	{
		const char* charname = (const char*)val1;

		PACKET_CZ_SHIFT packet;
		packet.PacketType = HEADER_CZ_SHIFT;
		memset(packet.CharacterName, '\0', sizeof(packet.CharacterName));
		strcpy(packet.CharacterName, charname);
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 171: //MM_RECALL_AID
	{
		const char* accname = (const char*)val1;

		PACKET_CZ_RECALL packet;
		packet.PacketType = HEADER_CZ_RECALL;
		memset(packet.AccountName, '\0', sizeof(packet.AccountName));
		strcpy(packet.AccountName, accname);
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 172: //MM_RECALL_GID
	{
		const char* charname = (const char*)val1;

		PACKET_CZ_RECALL_GID packet;
		packet.PacketType = HEADER_CZ_RECALL_GID;
		memset(packet.CharacterName, '\0', sizeof(packet.CharacterName));
		strcpy(packet.CharacterName, charname);
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 173: //MM_FORCING_MOVE_AID
	break;
	case 174: //MM_FORCING_MOVE_GID
	break;
	case 175: //MM_BILLING_INFO
	{
		PACKET_CZ_REQ_REMAINTIME packet;
		packet.PacketType = HEADER_CZ_REQ_REMAINTIME;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
//	case 176: //MM_MINI_GAME
//		//default
//	break;
	case 177: //MM_SELECT_SPELL
	{
		int SKID = (int)val1;

		PACKET_CZ_SELECTAUTOSPELL packet;
		packet.PacketType = HEADER_CZ_SELECTAUTOSPELL;
		packet.SKID = SKID;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 178: //MM_SEND_TEXT_TO_NPC
	{
		unsigned long npcAID = (unsigned long)val1;
		const char* text = (const char*)val2;

		char value[256];
		strcpy(value, text);

		if( m_world->CWorld::GetGameActorByAID(npcAID) == NULL )
			break;

		char buf[1024];
		PACKET_CZ_INPUT_EDITDLGSTR& packet = *(PACKET_CZ_INPUT_EDITDLGSTR*)buf;
		packet.PacketType = HEADER_CZ_INPUT_EDITDLGSTR;
		packet.PacketLength = sizeof(packet) + strlen(value) + 1;
		packet.NAID = npcAID;
		memcpy(packet.Text, value, strlen(value) + 1);
		g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
	}
	break;
	case 179: //MM_SONG_TALK
	{
		SEX_TYPE gender = (SEX_TYPE)val1;

		const char* talkFile;
		if( gender == SEX_FEMALE ) talkFile = "DC_scream.txt";
		else if( gender == SEX_MALE ) talkFile = "BA_frostjoke.txt";

		CFile fp;
		if( !fp.CFile::Open(talkFile, 0) )
			break;

		size_t talkSize = fp.CFile::GetLength();
		char* talkData = new char[talkSize + 1];
		fp.CFile::Read(talkData, talkSize);
		talkData[talkSize] = '\0';
		fp.CFile::Close();

//		mystd::string unusedStr = ""; //FIXME: unused variable?
//		mystd::vector<mystd::string> unsedStrVec; // FIXME: unused variable?

		int targetLine;
		if( gender == SEX_FEMALE ) targetLine = rand() % 114 + 1;
		else if( gender == SEX_MALE ) targetLine = rand() % 117 + 1;

		char msg[256];
		char* pmsg = &msg[0];
		int8_t curLine = 0;

		for( size_t i = 0; i < talkSize; ++i )
		{
			char c = talkData[i];
			if( c == '\r' )
				++curLine;

			if( curLine == targetLine )
			{
				if( c != '\r' && c != '\n' && c != '\t' )
				{
					*pmsg++ = c;
					*pmsg = '\0';
				}
			}
			else
			if( curLine == targetLine + 1 )
				break;
		}

		if( talkData != NULL )
			delete[] talkData;

		char chat[246+1];
		sprintf(chat, "%s : %s", g_session.CSession::GetCharName(), DataTxtDecode(msg));
		chat[sizeof(chat)-1] = '\0';
		size_t chatLen = strlen(chat);

		g_windowMgr.UIWindowMgr::ClearChatMsg();

		char buf[1024];
		PACKET_CZ_REQUEST_CHAT& packet = *(PACKET_CZ_REQUEST_CHAT*)buf;
		packet.PacketType = HEADER_CZ_REQUEST_CHAT;
		packet.PacketLength = sizeof(packet) + chatLen + 1;
		memcpy(packet.Text, chat, chatLen + 1);
		g_connection.CRagConnection::SendPacket(packet.PacketLength, (char*)&packet);
	}
	break;
	case 180: //MM_REQ_ACCOUNT_NAME
	{
		unsigned long AID = (unsigned long)val1;

		PACKET_CZ_REQ_ACCOUNTNAME packet;
		packet.PacketType = HEADER_CZ_REQ_ACCOUNTNAME;
		packet.AID = AID;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 181: //MM_JOIN_COUPLE
	{
		int answer = (int)val1;

		PACKET_CZ_JOIN_COUPLE packet;
		packet.PacketType = HEADER_CZ_JOIN_COUPLE;
		packet.AID = m_lastCouplePacketAid;
		packet.GID = m_lastCouplePacketGid;
		packet.answer = answer;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 182: //MM_CONFORM_MAKEGROUP
	{
		unsigned char itemPickupRule = (unsigned char)val2;
		unsigned char itemDivisionRule = (unsigned char)val3;

		PACKET_CZ_MAKE_GROUP2 packet;
		packet.PacketType = HEADER_CZ_MAKE_GROUP2;
		strncpy(packet.groupName, g_session.m_partyRequestName.c_str(), sizeof(packet.groupName)); //FIXME: zero terminator
		packet.ItemPickupRule = itemPickupRule;
		packet.ItemDivisionRule = itemDivisionRule;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	case 183: //MM_DORIDORI
	{
		PACKET_CZ_DORIDORI packet;
		packet.PacketType = HEADER_CZ_DORIDORI;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
//	case 184: //MM_ADDGUILDPOS
//		//default (not implemented)
//	break;
//	case 185: //MM_DELETEGUILDPOS
//		//default (not implemented)
//	break;
//	case 186: //MM_DELETEGUILDPOSALL
//		//default (not implemented)
//	break;
	case 187: //MM_JOIN_BABY
	{
		int answer = (int)val1;

		PACKET_CZ_JOIN_BABY packet;
		packet.PacketType = HEADER_CZ_JOIN_BABY;
		packet.AID = m_lastCouplePacketAid;
		packet.GID = m_lastCouplePacketGid;
		packet.answer = answer;
		g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(packet.PacketType), (char*)&packet);
	}
	break;
	default:
		return this->CMode::SendMsg(messageId, val1, val2, val3);
	break;
	};

	return 0;
}


//hook_method<CWorld* (CGameMode::*)(void)> CGameMode::_GetWorld(SAKEXE, "CGameMode::GetWorld");
CWorld* CGameMode::GetWorld(void) // line ??
{
//	return (this->*_GetWorld)();

	return m_world;
}


//hook_method<CView* (CGameMode::*)(void)> CGameMode::_GetView(SAKEXE, "CGameMode::GetView");
CView* CGameMode::GetView(void)
{
//	return (this->*_GetView)();

	return m_view;
}


hook_method<void (CGameMode::*)(void)> CGameMode::_ChatDori(SAKEXE, "CGameMode::ChatDori");
void CGameMode::ChatDori(void) // line 3028-3042 (GameMode2.cpp)
{
	return (this->*_ChatDori)();

	PACKET_CZ_REQ_GIVE_MANNER_POINT p;
	p.PacketType = HEADER_CZ_REQ_GIVE_MANNER_POINT;
	p.otherAID = g_session.CSession::GetAid();
	p.type = 2;
	p.point = 10;
	g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(p.PacketType), (char*)&p);
}


hook_method<void (CGameMode::*)(void)> CGameMode::_Initialize(SAKEXE, "CGameMode::Initialize");
void CGameMode::Initialize(void) // line 496-728
{
	return (this->*_Initialize)();

	this->CMode::Initialize();
	m_actorNameList.clear();
	m_actorNameListByGID.clear();
	m_actorPosList.clear();
	m_pickupReqItemNaidList.clear();
	m_actorNameReqTimer.clear();
	m_menuIdList.clear();
	m_partyPosList.clear();
	m_compassPosList.clear();
	m_visibleTrapList.clear();
	g_snapMgr.CSnapMgr::RemoveAll();
	g_windowMgr.UIWindowMgr::RemoveAllWindowsExceptChatWnd();
	g_windowMgr.UIWindowMgr::SetWallpaper(NULL);
	g_windowMgr.UIWindowMgr::MakeWindow(WID_BASICINFOWND);
	m_loopCond = TRUE;
	g_drawRect.left = 0;
	g_drawRect.right = 0;
	g_drawRect.top = 0;
	g_drawRect.bottom = 0;
	RECT rect;
	rect.right = g_renderer->CRenderer::GetWidth();
	rect.bottom = g_renderer->CRenderer::GetHeight();
	rect.left = 0;
	rect.top = 0;
	g_actorPickNode.CActorPickNode::MakeQuardTree(1, rect);
	g_pathFinder.CPathFinder::SetMap(m_world->m_attr);
	g_isBlackWorld = 0;
	m_fadeInCount = 1;
	m_mouseSnapDiff.x = 0.0f;
	m_mouseSnapDiff.y = 0.0f;
	m_leftBtnClickTick = 0;
	m_oldMouseX = g_mouse.CMouse::GetXPos();
	m_oldMouseY = g_mouse.CMouse::GetYPos();
	m_rBtnClickX = g_mouse.CMouse::GetXPos();
	m_rBtnClickY = g_mouse.CMouse::GetYPos();
	m_noMove = 0;
	m_isOnQuest = 0;
	m_isPlayerDead = 0;
	m_nameBalloon = NULL;
	m_targetNameBalloon = NULL;
	m_broadcastBalloon = NULL;
	m_skillNameBalloon = NULL;
	m_skillMsgBalloon = NULL;
	m_skillUsedMsgBalloon = NULL;
	m_playerGage = NULL;
	m_nameActorAid = 0;
	m_nameBalloonWidth = 0;
	m_nameBalloonHeight = 0;
	m_nameDisplayed = 1;
	m_nameDisplayed2 = 1;
	m_waitingUseItemAck = 0;
	m_waitingItemThrowAck = 0;
	m_waitingReqStatusAck = 0;
	m_dragInfo.m_dragType = DT_NODRAG;
	m_dragInfo.m_dragItemIndex = 0;
	m_dragInfo.m_numDragItem = 0;
	m_dragInfo.m_slotNum = -1;
	m_dragInfo.m_isIdentified = false;
	m_lastNaid = 0;
	m_menuTargetAID = 0;
	m_lastPcGid = 0;
	m_lastMonGid = 0;
	m_lastLockOnMonGid = 0;
	m_isAutoMoveClickOn = 1;
	m_isWaitingWhisperSetting = 0;
	m_isWaitingEnterRoom = 0;
	m_isWaitingAddExchangeItem = 0;
	m_waitingWearEquipAck = timeGetTime() - 2000;
	m_waitingTakeoffEquipAck = timeGetTime() - 2000;
	m_isReqUpgradeSkillLevel = 0;
	m_exchangeItemCnt = 0;
	m_isWaitingCancelExchangeItem = 0;
	m_sameChatRepeatCnt = 0;
	m_numNotifyTime = 0;
	m_lastChat = "";
	m_skillUseInfo.m_skillUseType = SUT_NOSKILL;
	m_skillUseInfo.m_skillId = 0;
	g_isGoodSkillHanging = 0;
	m_lastCardItemIndex = 0;
	m_showImageInfo.type = -1;
	m_SkillBallonSkillId = -1;
	m_nameBalloonType = 0;
	this->CGameMode::InitNameBalloonPosFromReg();
	g_mouse.CMouse::ResetButtonState();
	m_receiveSyneRequestTime = 1;
	m_isReqEmotion = 0;
	m_syncRequestTime = timeGetTime();
	m_usedCachesUnloadTick = timeGetTime();
	m_reqEmotionTick = timeGetTime();
	m_noMoveStartTick = timeGetTime();
	m_lastEmblemReqTick = timeGetTime();
	m_lastNameWaitingListTick = timeGetTime();
	m_broadCastTick = timeGetTime();
	m_skillUsedTick = timeGetTime();
	m_reqTickChatRoom = timeGetTime();
	m_reqTickMerchantShop = timeGetTime();
	SetListenerOrient(m_view->CView::GetDestLongitude());
	this->SendMsg(MM_TOGGLE_PLAYERGAGE, 0, 0, 0);

	if( g_isStopByLogin != 0 )
	{
		g_isStopByLogin = 0;
		g_guildInfo.GuildInfo::Init();

		if( g_serviceType == ServiceKorea )
			g_modeMgr.CModeMgr::GetCurMode()->SendMsg(MM_PROCESS_TALK_TYPE, TT_HELP, 0, 0);

		g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
		g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_LIST_COMMAND), 0xFFE6E6, 0);

		char ip[16];
		strcpy(ip, inet_ntoa(*(in_addr*)&g_session.m_lastLoginIP));
	}
	else
	{
		g_guildInfo.GuildInfo::Init2();
	}

	g_session.CSession::ClearPlusValue();
	g_session.CSession::ChangeXorValue();
	g_session.CSession::ClearItem();
	g_session.CSession::ClearEquipItem();
	g_session.CSession::ClearStoreItem();
	g_session.CSession::ClearDealItems();
	g_session.CSession::ClearMerchantItem();
	g_session.CSession::ClearMerchantHopeToSellItem();
	g_session.CSession::ClearMerchantMyShopItem();
	g_session.CSession::ClearMerchantMirrorItem();

	static int oneTime = 0;
	if( oneTime == 0 )
	{
		oneTime = 1;

		if( g_showTipsAtStartup != 0 && g_tipOfTheDay.CTipOfTheDay::Size() != 0 ) //inlined
			g_windowMgr.UIWindowMgr::MakeWindow(WID_TIPOFTHEDAYWND);
	}

	PACKET_CZ_NOTIFY_ACTORINIT cz_notify_actorinit;
	cz_notify_actorinit.PacketType = HEADER_CZ_NOTIFY_ACTORINIT;
	g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(cz_notify_actorinit.PacketType), (char*)&cz_notify_actorinit);

	m_receiveSyneRequestTime = 0;
	m_syncRequestTime = timeGetTime();

	PACKET_CZ_REQUEST_TIME cz_request_time;
	cz_request_time.PacketType = HEADER_CZ_REQUEST_TIME;
	cz_request_time.clientTime = timeGetTime();
	g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(cz_request_time.PacketType), (char*)&cz_request_time);

	if( g_pingLog )
	{
		g_pingLogList.push_back(timeGetTime());
		if( g_pingLogStart == 0 )
			g_pingLogStart = g_pingLogList.front();
	}

	g_Weather.CWeather::Reset();

	if( strcmp(m_rswName, "xmas_fild01.rsw") == 0 || strcmp(m_rswName, "xmas.rsw") == 0 )
	{
		if( g_session.m_isEffectOn )
			g_Weather.CWeather::LaunchSnow();
		else
			g_Weather.CWeather::StopSnow();
	}
	else
	{
		g_Weather.CWeather::StopSnow();
		g_Weather.CWeather::StopSakura();
	}

	if( strcmp(m_rswName, "pay_arche.rsw") == 0 && g_serviceType == ServiceTaiwan )
	{
		if( g_session.m_isEffectOn )
			g_Weather.CWeather::LaunchSakura();
		else
			g_Weather.CWeather::StopSakura();
	}

	if( strcmp(m_rswName, "gef_fild07.rsw") == 0 || strcmp(m_rswName, "mjolnir_01.rsw") == 0 )
	{
		if( g_session.m_isEffectOn )
			g_Weather.CWeather::LaunchCloud(0);
	}
	else
	if( strcmp(m_rswName, "yuno.rsw") == 0 || strcmp(m_rswName, "gonryun.rsw") == 0 || strcmp(m_rswName, "gon_dun02.rsw") == 0 )
	{
		if( g_session.m_isEffectOn )
			g_Weather.CWeather::LaunchCloud(1);
	}
	else
	if( strcmp(m_rswName, "valkyrie.rsw") == 0 )
	{
		if( g_session.m_isEffectOn )
			g_Weather.CWeather::LaunchCloud(2);
	}
	else
	if( strcmp(m_rswName, "comodo.rsw") == 0 && g_serviceType != ServiceJapan )
	{
		if( g_session.m_isEffectOn )
			g_Weather.CWeather::LaunchPokJuk();
	}
}


hook_method<void (CGameMode::*)(int fogOn)> CGameMode::_MakeFog(SAKEXE, "CGameMode::MakeFog");
void CGameMode::MakeFog(int fogOn)
{
	return (this->*_MakeFog)(fogOn);

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_SetCamera(SAKEXE, "CGameMode::SetCamera");
void CGameMode::SetCamera(void) // line 439-472
{
	return (this->*_SetCamera)();

	m_view->CView::SetCurAt(m_world->m_player->m_pos.x, m_world->m_player->m_pos.y, m_world->m_player->m_pos.z);
	m_view->CView::SetDestAt(m_world->m_player->m_pos.x, m_world->m_player->m_pos.y, m_world->m_player->m_pos.z);

	m_canRotateView = ( g_session.CSession::IsIndoorRswName(m_rswName) == 0 );
	float farDist;
	float maxPitch;

	if( m_canRotateView )
	{
		farDist = FAR_DIST;
		maxPitch = 20.0f;

		g_viewLatitude = g_outdoorViewLatitude;
		g_viewDistance = g_outdoorViewDistance;
	}
	else
	{
		farDist = AVG_DIST;
		maxPitch = 10.0f;

		m_fixedLongitude = 45.0f;
		m_view->CView::SetCurLongitude(m_fixedLongitude);
		m_view->CView::SetDestLongitude(m_fixedLongitude);

		g_viewLatitude = g_indoorViewLatitude;
		g_viewDistance = g_indoorViewDistance;
	}

	if( g_viewLatitude < -45.0f - maxPitch )
		g_viewLatitude = -45.0f - maxPitch;

	if( g_viewLatitude > -45.0f + maxPitch )
		g_viewLatitude = -45.0f + maxPitch;

	if( g_viewDistance < CLOSE_DIST )
		g_viewDistance = CLOSE_DIST;

	if( g_viewDistance > farDist )
		g_viewDistance = farDist;

	m_view->CView::SetCurLatitude(g_viewLatitude);
	m_view->CView::SetDestLatitude(g_viewLatitude);
	m_view->CView::SetCurDistance(g_viewDistance);
	m_view->CView::SetDestDistance(g_viewDistance);
}


hook_method<void (CGameMode::*)(void)> CGameMode::_SaveCamera(SAKEXE, "CGameMode::SaveCamera");
void CGameMode::SaveCamera(void) // line 475-483
{
	return (this->*_SaveCamera)();

	if( m_canRotateView )
	{
		g_outdoorViewLatitude = g_viewLatitude;
		g_outdoorViewDistance = g_viewDistance;
	}
	else
	{
		g_indoorViewLatitude = g_viewLatitude;
		g_indoorViewDistance = g_viewDistance;
	}
}


hook_method<void (CGameMode::*)(CGameObject* gameObject)> CGameMode::_PushGameObject(SAKEXE, "CGameMode::PushGameObject");
void CGameMode::PushGameObject(CGameObject* gameObject)
{
	return (this->*_PushGameObject)(gameObject);

	m_world->m_gameObjectList.push_back(gameObject);
}


hook_method<void (CGameMode::*)(void)> CGameMode::_RemoveGameActorAllAndMake(SAKEXE, "CGameMode::RemoveGameActorAllAndMake");
void CGameMode::RemoveGameActorAllAndMake(void) // line 731
{
	return (this->*_RemoveGameActorAllAndMake)();

	//TODO
}


//hook_method<void (CGameMode::*)(vector2d& pos)> CGameMode::_MakeMousePointer(SAKEXE, "CGameMode::MakeMousePointer");
void CGameMode::MakeMousePointer(vector2d& pos) // inlined
{
//	return (this->*_MakeMousePointer)();

	pos.x = (float)g_mouse.CMouse::GetXPos();
	pos.y = (float)g_mouse.CMouse::GetYPos();
}


hook_method<void (CGameMode::*)(CActorPickInfo* actorInfo, int processType)> CGameMode::_MakeMenu(SAKEXE, "CGameMode::MakeMenu");
void CGameMode::MakeMenu(CActorPickInfo* actorInfo, int processType) // line 3312-3500
{
	return (this->*_MakeMenu)(actorInfo, processType);

	//TODO
}


hook_method<void (CGameMode::*)(CActorPickInfo* actorInfo, int processType)> CGameMode::_ProcessMouseSnap(SAKEXE, "CGameMode::ProcessMouseSnap");
void CGameMode::ProcessMouseSnap(CActorPickInfo* actorInfo, int processType) // line 3282-3309
{
	return (this->*_ProcessMouseSnap)(actorInfo, processType);

	//TODO
}


hook_method<void (CGameMode::*)(int processType)> CGameMode::_ProcessWheel(SAKEXE, "CGameMode::ProcessWheel");
void CGameMode::ProcessWheel(int processType) // line 3503-3578
{
	return (this->*_ProcessWheel)(processType);

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_ProcessRBtn(SAKEXE, "CGameMode::ProcessRBtn");
void CGameMode::ProcessRBtn(void) // line 3581-3691
{
	return (this->*_ProcessRBtn)();

	//TODO
}


hook_method<int (CGameMode::*)(int processType)> CGameMode::_ProcessGroundPick(SAKEXE, "CGameMode::ProcessGroundPick");
int CGameMode::ProcessGroundPick(int processType) // line 3694
{
	return (this->*_ProcessGroundPick)(processType);

	ENUM_SKILL_USE_TYPE skillUseType = m_skillUseInfo.m_skillUseType;
	if( skillUseType == SUT_TO_CHARACTER || skillUseType == SUT_TO_ITEM || skillUseType == SUT_TO_ALL )
		return processType;

	int dx = -1;
	int dy = -1;
	if( !this->CGameMode::GetGroundAttrPos(dx, dy) )
		return processType;

	if( m_skillUseInfo.m_skillUseType == SUT_TO_GROUND && g_mouse.CMouse::GetLBtn() == BTN_DOWN && (processType != 0 && processType != 2) )
	{
		processType = 1;
		m_world->m_player->SendMsg(NULL, 65, m_skillUseInfo.m_skillId, dx, dy);
		m_world->m_player->SendMsg(NULL, 90, m_skillUseInfo.m_useLevel, 0, 0);
	}

	if( GetAsyncKeyState(VK_CONTROL) >> 8 || m_noMove || (processType != 0 && processType != 2) || m_dragInfo.m_dragType )
		return processType;

	if( g_session.m_isAttrIndicator )
	{
		g_groundAttrPosInfo.x = dx;
		g_groundAttrPosInfo.y = dy;

		CAttrCell* cell = m_world->m_attr->C3dAttr::GetCell(dx, dy);
		if( cell == NULL || cell->flag == 1 )
		{
			g_groundAttrPosInfo.cellColor = 0xFEFF0000;
			g_groundAttrPosInfo.isRendered = 1;
		}
		else
		if( cell->flag == 5 )
		{
			g_groundAttrPosInfo.cellColor = 0xFEFFFF00;
			g_groundAttrPosInfo.isRendered = 1;
		}
		else
		{
			g_groundAttrPosInfo.cellColor = 0x6600FFAA;
			g_groundAttrPosInfo.isRendered = 0;
		}
	}

	bool autoClick = true;
	if( m_world->m_player->m_proceedType || g_mouse.CMouse::GetLBtn() != BTN_PRESSED || timeGetTime() <= m_leftBtnClickTick + 600 || !m_isAutoMoveClickOn )
		autoClick = false;

	if( autoClick || g_mouse.CMouse::GetLBtn() == BTN_DOWN && g_mouse.CMouse::GetRBtn() != BTN_PRESSED && timeGetTime() > m_leftBtnClickTick + 225 )
	{
		m_leftBtnClickTick = timeGetTime();
		if( GetAsyncKeyState(VK_SHIFT) >> 8 || g_windowMgr.UIWindowMgr::GetChatRoom() || m_world->m_player->m_stateId == STATEID_SIT )
		{
			m_world->m_player->SendMsg(NULL, 16, dx, dy, 0);
			return processType;
		}

		if( this->CGameMode::IsValidCell(dx, dy) || this->CGameMode::GetClosestValidCell(dx, dy) )
		{
			if( g_windowMgr.UIWindowMgr::GetMenu() != NULL )
				g_windowMgr.UIWindowMgr::DeleteWindow(WID_MENUWND);

			m_world->m_player->SendMsg(NULL, 17, dx, dy, 0);
			return processType;
		}
	}

	return processType;
}


hook_method<bool (CGameMode::*)(void)> CGameMode::_AttackSkillOverWeightMessage(SAKEXE, "CGameMode::AttackSkillOverWeightMessage");
bool CGameMode::AttackSkillOverWeightMessage(void) // line 2529
{
	return (this->*_AttackSkillOverWeightMessage)();

	if( 100 * g_session.CSession::GetWeight() / max(1,g_session.CSession::GetMaxWeight()) < 90 )
		return false;

	g_windowMgr.UIWindowMgr::SendMsg(UIM_OPENCHATWND, 0, 0, 0);
	g_windowMgr.UIWindowMgr::SendMsg(UIM_PUSHINTOCHATHISTORY, (int)MsgStr(MSI_NO_ATTACK_OVERWEIGHT), 0x0000FF, 0);
	return true;
}


hook_method<void (CGameMode::*)(void)> CGameMode::_ProcessReqEmblem(SAKEXE, "CGameMode::ProcessReqEmblem");
void CGameMode::ProcessReqEmblem(void) // line 3753-3758
{
	return (this->*_ProcessReqEmblem)();

	if( m_emblemReqGdidQueue.size() != 0 && timeGetTime() > m_lastEmblemReqTick + 5000 )
	{
		this->SendMsg(121, m_emblemReqGdidQueue.front(), 0, 0);
		m_lastEmblemReqTick = timeGetTime();
	}
}


hook_method<void (CGameMode::*)(void)> CGameMode::_ProcessNameWaitingTimer(SAKEXE, "CGameMode::ProcessNameWaitingTimer");
void CGameMode::ProcessNameWaitingTimer(void) // line 3761-3766
{
	return (this->*_ProcessNameWaitingTimer)();

	if( timeGetTime() > m_lastNameWaitingListTick + 1000 )
	{
		g_windowMgr.UIWindowMgr::RefreshNameWaitingWindowList();
		m_lastNameWaitingListTick = timeGetTime();
	}
}


hook_method<void (CGameMode::*)(void)> CGameMode::_ProcessPeriodicalJobs(SAKEXE, "CGameMode::ProcessPeriodicalJobs");
void CGameMode::ProcessPeriodicalJobs(void) // line 3769-3772
{
	return (this->*_ProcessPeriodicalJobs)();

	this->CGameMode::ProcessReqEmblem(); // inlined
	this->CGameMode::ProcessNameWaitingTimer(); // inlined
}


hook_method<void (CGameMode::*)(float cx, float cz, int& sx, int& sy, int& cellX, int& cellY)> CGameMode::_GetServerCoor(SAKEXE, "?GetServerCoor@CGameMode@@QAEXMMAAH000@Z");
void CGameMode::GetServerCoor(float cx, float cz, int& sx, int& sy, int& cellX, int& cellY) // line 2049-2057
{
	return (this->*_GetServerCoor)(cx, cz, sx, sy, cellX, cellY);

	C3dAttr* attr = m_world->m_attr;

	int centerX = attr->m_width / 2;
	int centerY = attr->m_height / 2;
	float deltaX = cx / attr->m_zoom;
	float deltaY = cz / attr->m_zoom;

	sx = (int)floor(centerX + deltaX);
	sy = (int)floor(centerY + deltaY);
	cellX = (int)floor((centerX + deltaX - sx) * 16.0) % 16;
	cellY = (int)floor((centerY + deltaY - sy) * 16.0) % 16;
}


hook_method<void (CGameMode::*)(float cx, float cz, int& sx, int& sy)> CGameMode::_GetServerCoor2(SAKEXE, "?GetServerCoor@CGameMode@@QAEXMMAAH0@Z");
void CGameMode::GetServerCoor(float cx, float cz, int& sx, int& sy) // line 2060-2065
{
	return (this->*_GetServerCoor2)(cx, cz, sx, sy);

	C3dAttr* attr = m_world->m_attr;

	int centerX = attr->m_width / 2;
	int centerY = attr->m_height / 2;
	float deltaX = cx / attr->m_zoom;
	float deltaY = cz / attr->m_zoom;

	sx = (int)floor(centerX + deltaX);
	sy = (int)floor(centerY + deltaY);
}


hook_method<void (CGameMode::*)(int sx, int sy, int subX, int subY, float& cx, float& cz)> CGameMode::_GetClientCoor(SAKEXE, "?GetClientCoor@CGameMode@@QAEXHHHHAAM0@Z");
void CGameMode::GetClientCoor(int sx, int sy, int subX, int subY, float& cx, float& cz) // line 2075-2078
{
	return (this->*_GetClientCoor)(sx, sy, subX, subY, cx, cz);

	//TODO
}


hook_method<void (CGameMode::*)(int sx, int sy, float& cx, float& cz)> CGameMode::_GetClientCoor2(SAKEXE, "?GetClientCoor@CGameMode@@QAEXHHAAM0@Z");
void CGameMode::GetClientCoor(int sx, int sy, float& cx, float& cz) // line 2068-2072
{
	return (this->*_GetClientCoor2)(sx, sy, cx, cz);

	//TODO
}


hook_method<void (CGameMode::*)(int& sx, int& sy, int& dx, int& dy)> CGameMode::_ConvertToNoRedCell(SAKEXE, "CGameMode::ConvertToNoRedCell");
void CGameMode::ConvertToNoRedCell(int& sx, int& sy, int& dx, int& dy)
{
	return (this->*_ConvertToNoRedCell)(sx, sy, dx, dy);

	//TODO
}


hook_method<void (CGameMode::*)(float x1, float y1, float x2, float y2, int& dx, int& dy, int numCell)> CGameMode::_ConvertToNumCellCloseAndFindNoRedCell(SAKEXE, "CGameMode::ConvertToNumCellCloseAndFindNoRedCell");
void CGameMode::ConvertToNumCellCloseAndFindNoRedCell(float x1, float y1, float x2, float y2, int& dx, int& dy, int numCell)
{
	return (this->*_ConvertToNumCellCloseAndFindNoRedCell)(x1, y1, x2, y2, dx, dy, numCell);

	//TODO
}


hook_method<bool (CGameMode::*)(int& sx, int& sy, int& dx, int& dy, int numCell)> CGameMode::_IsInsideCell(SAKEXE, "CGameMode::IsInsideCell");
bool CGameMode::IsInsideCell(int& sx, int& sy, int& dx, int& dy, int numCell) // line 1948
{
	return (this->*_IsInsideCell)(sx, sy, dx, dy, numCell);

	//TODO
}


hook_method<bool (CGameMode::*)(int x, int y)> CGameMode::_IsRedCell(SAKEXE, "CGameMode::IsRedCell");
/// Returns true if the cell is not walkable.
bool CGameMode::IsRedCell(int x, int y) // line 2149
{
	return (this->*_IsRedCell)(x, y);

	CAttrCell* cell = m_world->m_attr->C3dAttr::GetCell(x, y);
	if( cell == NULL ) return true;
	if( cell->flag == 1 ) return true;
	if( cell->flag == 5 ) return true;
	return false;
}


hook_method<bool (CGameMode::*)(int x, int y)> CGameMode::_IsValidCell(SAKEXE, "CGameMode::IsValidCell");
bool CGameMode::IsValidCell(int x, int y) // line 2170
{
	return (this->*_IsValidCell)(x, y);

	if( this->CGameMode::IsRedCell(x,y) ) //inlined
		return false;

	CPlayer* player = m_world->m_player;
	if( player->m_destCellX == x && player->m_destCellZ == y )
		return false;

	int sx, sy;
	int cellX, cellY;
	this->CGameMode::GetServerCoor(player->m_pos.x, player->m_pos.z, sx, sy, cellX, cellY);
	if( !this->CGameMode::CanFindPath(sx, sy, cellX, cellY, x, y) )
		return false;

	if( this->CGameMode::IsRegisterCell(x,y) ) //inlined
		return false;

	return true;
}


hook_method<bool (CGameMode::*)(int sx, int sy, int cellX, int cellY, int dx, int dy)> CGameMode::_CanFindPath(SAKEXE, "CGameMode::CanFindPath");
/// Returns true is the cell can be reached.
bool CGameMode::CanFindPath(int sx, int sy, int cellX, int cellY, int dx, int dy) // line 2081
{
	return (this->*_CanFindPath)(sx, sy, cellX, cellY, dx, dy);

	CPathInfo pathInfo;
	return g_pathFinder.CPathFinder::FindPath(timeGetTime(), sx, sy, cellX, cellY, dx, dy, 150, &pathInfo);
}


hook_method<bool (CGameMode::*)(int& dx, int& dy)> CGameMode::_GetClosestValidCell(SAKEXE, "CGameMode::GetClosestValidCell");
bool CGameMode::GetClosestValidCell(int& dx, int& dy) // line 2087
{
	return (this->*_GetClosestValidCell)(dx, dy);

	CPlayer* player = m_world->m_player;
	int sx, sy, cellX, cellY;// current player position
	this->CGameMode::GetServerCoor(player->m_pos.x, player->m_pos.y, sx, sy, cellX, cellY);
	int dx_ = dx;
	int dy_ = dy;
	int deltaX = sx - dx_;// position of the player from the destination coordinates
	int deltaY = sy - dy_;
	int offset[18] = {
		 0, 0,
		 1, 0,
		 1, 1,
		 1,-1,
		-1, 0,
		-1, 1,
		-1,-1,
		 0, 1,
		 0,-1};
	if ( abs(deltaX) < abs(deltaY) )
	{// vertical movement
		if( deltaY == 0 )
			return false;// already there, deltaX and deltaY are 0

		int signY = 2 * ( deltaY > 0 ) - 1;
		if( sy == dy_ )
			return false;// FIXME impossible path

		int inc = deltaX * signY;
		for( int y = dy_, incX = 0/*deltaX * (dy_ - dy_)*/; y != sy ; y += signY, incX += inc )
		{
			int x = dx_ + incX / deltaY;
			for( int i = 0; i < countof(offset) / 2; ++i )
			{
				int destX = x + offset[i * 2];
				int destY = y + offset[i * 2 + 1];

				if( this->CGameMode::IsRedCell(destX,destY) ) //inlined
					continue; // cell is not walkable

				if( this->CGameMode::IsRegisterCell(destX,destY) ) //inlined
					continue; // cell is occupied

				if( !this->CGameMode::CanFindPath(sx, sy, cellX, cellY, destX, destY) )
					return false; // cell is not reachable

				dx = destX;
				dy = destY;
				return true;
			}
		}
	}
	else
	{// horizontal movement
		if( deltaX == 0 )
			return false;// already there, deltaX and deltaY are 0

		int signX = 2 * ( deltaX > 0 ) - 1;
		if( sx == dx_ )
			return false;// FIXME impossible path

		int inc = deltaY * signX;
		for( int x = dx_, incY = 0/*deltaY * (dx_ - dx_)*/; x != sx ; x += signX, incY += inc )
		{
			int y = dy_ + incY / deltaX;
			for( int i = 0; i < countof(offset) / 2; ++i )
			{
				int destX = x + offset[i * 2];
				int destY = y + offset[i * 2 + 1];

				if( this->CGameMode::IsRedCell(destX,destY) ) //inlined
					continue; // cell is not walkable

				if( this->CGameMode::IsRegisterCell(destX,destY) ) //inlined
					continue; // cell is occupied

				if( !this->CGameMode::CanFindPath(sx, sy, cellX, cellY, destX, destY) )
					return false; // cell is not reachable

				dx = destX;
				dy = destY;
				return true;
			}
		}
	}

	return false;
}


hook_method<bool (CGameMode::*)(int x, int y)> CGameMode::_IsRegisterCell(SAKEXE, "CGameMode::IsRegisterCell");
/// Returns true if the cell is occupied.
bool CGameMode::IsRegisterCell(int x, int y) // line 2159
{
	return (this->*_IsRegisterCell)(x, y);

	for( mystd::map<unsigned long,CellPos>::iterator it = m_actorPosList.begin(); it != m_actorPosList.end(); ++it )
		if( it->second.x == x && it->second.y == y )
			return true;// cell is occupied

	return false;// cell is empty
}


hook_method<void (CGameMode::*)(float cx, float cy, int color)> CGameMode::_ShowMousePointer(SAKEXE, "CGameMode::ShowMousePointer");
void CGameMode::ShowMousePointer(float cx, float cy, int color) // line 1493
{
	return (this->*_ShowMousePointer)(cx, cy, color);

	//TODO
}


hook_method<void (CGameMode::*)(int time)> CGameMode::_HideMousePointer(SAKEXE, "CGameMode::HideMousePointer");
void CGameMode::HideMousePointer(int time) // line 1499
{
	return (this->*_HideMousePointer)(time);

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_ProcessInput(SAKEXE, "CGameMode::ProcessInput");
void CGameMode::ProcessInput(void) // line 3776-3864
{
	return (this->*_ProcessInput)();

	g_mouse.CMouse::ReadState();
	int processType = g_windowMgr.UIWindowMgr::ProcessInput();
	g_windowMgr.UIWindowMgr::OnProcess();
	this->CGameMode::ProcessNameBalloon();
	this->CMode::ProcessHelpBalloon();
	this->CGameMode::ProcessRBtn();
	this->CGameMode::ProcessWheel(processType);
	this->CMode::ProcessKeyBoard();
	this->CGameMode::ProcessPeriodicalJobs(); // inlined

	if( processType == 2 )
		processType = 0;

	if( m_skillUseInfo.m_skillUseType != SUT_NOSKILL )
	{
		if( g_session.m_isQ2begin == 0 )
		{
			if( g_mouse.CMouse::GetWheel() < 0 )
				this->SendMsg(107, 1, 0, 0);
			else
			if( g_mouse.CMouse::GetWheel() > 0 )
				this->SendMsg(106, 1, 0, 0);
		}
		g_session.m_isQ2begin = 0;
	}

	if( g_mouse.CMouse::GetLBtn() == BTN_UP )
	{
		m_world->m_player->SendMsg(NULL, 15, 0, 0, 0);
		this->SendMsg(18, g_mouse.CMouse::GetXPos(), g_mouse.CMouse::GetYPos(), 0);
		if( g_windowMgr.UIWindowMgr::GetMenu() != NULL )
			g_windowMgr.UIWindowMgr::DeleteWindow(WID_MENUWND);
		m_isAutoMoveClickOn = 1;
	}

	g_shiftKeyPressed = GetAsyncKeyState(VK_SHIFT) >> 8;

	vector2d pos;
	this->CGameMode::MakeMousePointer(pos); // inlined
	CActorPickInfo* actorInfo = g_actorPickNode.CActorPickNode::FindPickInfo(pos);

	if( g_windowMgr.UIWindowMgr::GetExchangeWnd() == NULL )
		this->CGameMode::MakeMenu(actorInfo, processType);
	this->CGameMode::ProcessMouseSnap(actorInfo, processType);
	this->CGameMode::HideCheck();

	if( m_isOnQuest || m_isPlayerDead || g_windowMgr.UIWindowMgr::GetExchangeWnd() || g_windowMgr.UIWindowMgr::GetItemStoreWnd() )
	{
		if( actorInfo != NULL && processType == 0 )
			this->CGameMode::MakeNameBalloon(actorInfo->m_gid);
	}
	else
	{
		processType = this->CGameMode::ProcessActorPick(processType, actorInfo);
		processType = this->CGameMode::ProcessGroundPick(processType);
		this->CGameMode::ProcessLockOnMouse();
	}

	if( g_session.m_isBattle && g_session.m_isBmChat )
		this->SendMsg(78, 0, 0, 0);

	if( g_mouse.CMouse::GetLBtn() == BTN_DOWN )
	{
		this->SendMsg(78, 0, 0, 0);
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_PASSWORDWND);
		if( timeGetTime() > m_noMoveStartTick + 5000 )
			m_noMove = 0;
		m_leftBtnClickTick = timeGetTime();
	}

	if( m_skillUseInfo.m_skillUseType != SUT_NOSKILL )
	{
		if( processType == 0 )
			this->CMode::SetCursorAction(10);
	}
	else
	{
		if( processType == 0 && g_mouse.CMouse::GetRBtn() != BTN_PRESSED )
			this->CMode::SetCursorAction(0);
	}

	m_oldMouseX = g_mouse.CMouse::GetXPos();
	m_oldMouseY = g_mouse.CMouse::GetXPos();
}


hook_method<bool (CGameMode::*)(int& dx, int& dy)> CGameMode::_GetGroundAttrPos(SAKEXE, "CGameMode::GetGroundAttrPos");
bool CGameMode::GetGroundAttrPos(int& dx, int& dy) // line 3249-3279
{
	return (this->*_GetGroundAttrPos)(dx, dy);

	CRayPicker picker;
	ray3d ray;

	g_renderer->CRenderer::BuildRay(g_mouse.CMouse::GetXPos(), g_mouse.CMouse::GetYPos(), m_view->CView::GetFrom(), m_view->CView::GetViewMatrix(), &ray);
	picker.CRayPicker::Build(ray, m_world->CWorld::GetRootNode());

	float nearest = infinity;
	for( mystd::list<SceneGraphNode*>::const_iterator ni = picker.m_cubeletList.begin(); ni != picker.m_cubeletList.end(); ++ni )
	{
		SceneGraphNode* node = *ni;
		C3dAttr* attr = node->m_attr;

		for( int y = node->m_attrArea.top; y <= node->m_attrArea.bottom; ++y )
		{
			for( int x = node->m_attrArea.left; x <= node->m_attrArea.right; ++x )
			{
				float dist = attr->C3dAttr::RayTest(ray, x, y);
				if( dist < nearest )
				{
					nearest = dist;
					dx = x;
					dy = y;
				}
			}
		}
	}

	return ( nearest < infinity );
}


hook_method<void (CGameMode::*)(unsigned long aid)> CGameMode::_RemoveActorNameRequestTimer(SAKEXE, "CGameMode::RemoveActorNameRequestTimer");
void CGameMode::RemoveActorNameRequestTimer(unsigned long aid) // line 2219
{
	return (this->*_RemoveActorNameRequestTimer)(aid);

	//TODO
}


hook_method<const NamePair& (CGameMode::*)(unsigned long aid)> CGameMode::_GetActorName(SAKEXE, "CGameMode::GetActorName");
const NamePair& CGameMode::GetActorName(unsigned long aid) // line 2236
{
	return (this->*_GetActorName)(aid);

	if( m_actorNameList.find(aid) == m_actorNameList.end() )
	{
		this->CGameMode::RequestActorName(aid);
		static NamePair nullnamepair;
		return nullnamepair;
	}

	return m_actorNameList[aid];
}


hook_method<void (CGameMode::*)(unsigned long aid)> CGameMode::_RequestActorName(SAKEXE, "CGameMode::RequestActorName");
void CGameMode::RequestActorName(unsigned long aid) // line 2224
{
	return (this->*_RequestActorName)(aid);

	if( aid == 0 )
		return;

	mystd::map<unsigned long,unsigned long>::iterator it = m_actorNameReqTimer.find(aid);
	if( it != m_actorNameReqTimer.end() && timeGetTime() - it->second < 2500 )
		return; // already known and needs no refresh
	
	m_actorNameReqTimer[aid] = timeGetTime();

	PACKET_CZ_REQNAME p;
	p.PacketType = HEADER_CZ_REQNAME;
	p.AID = aid;
	g_connection.CRagConnection::SendPacket(g_connection.CRagConnection::GetPacketSize(HEADER_CZ_REQNAME), (char*)&p);

	NamePair& n = m_actorNameList[aid];
	n.NamePair::Clear();
}


hook_method<const NamePair& (CGameMode::*)(unsigned long gid)> CGameMode::_GetActorNameByGID(SAKEXE, "CGameMode::GetActorNameByGID");
const NamePair& CGameMode::GetActorNameByGID(unsigned long gid) // line 2286
{
	return (this->*_GetActorNameByGID)(gid);

	//TODO
}


hook_method<void (CGameMode::*)(unsigned long aid)> CGameMode::_MakeNameBalloon(SAKEXE, "CGameMode::MakeNameBalloon");
void CGameMode::MakeNameBalloon(unsigned long aid) // line 2321
{
	return (this->*_MakeNameBalloon)(aid);

	if( aid == 0 )
		return;

	m_nameActorAid = aid;

	CGameActor* actor = m_world->CWorld::GetGameActorByAID(aid);
	if( actor != NULL )
	{
		if( actor->CGameActor::GetJob() != JT_WARPNPC )
		{
			m_nameDisplayed = 0;
			this->CGameMode::MakeActorNameBalloon(actor);
		}
		return;
	}

	if( aid == g_session.CSession::GetAid() )
	{
		m_nameDisplayed = 0;
		this->CGameMode::MakeActorNameBalloon(m_world->m_player);
		return;
	}

	CItem* item = m_world->CWorld::GetItemByAID(aid);
	if( item != NULL )
	{
		mystd::string nameMsg = item->m_itemName.c_str();
		m_nameDisplayed = 0;
		this->CGameMode::MakeNameBalloonTextWindow((UIWindow**)&m_nameBalloon);
		m_nameBalloon->SetNameText(nameMsg.c_str());
		m_nameBalloon->SetEmblemResName("");
		m_nameBalloon->UIBalloonText::SetFntColor(0x95EFFF, 0);
		m_nameBalloonWidth = m_nameBalloon->UIWindow::GetWidth();
		m_nameBalloonHeight = m_nameBalloon->UIWindow::GetHeight();
		this->CGameMode::MoveBalloonTextWindow(m_nameBalloon, item);
	}
}


hook_method<void (CGameMode::*)(CGameActor* theActor)> CGameMode::_MakeActorNameBalloon(SAKEXE, "CGameMode::MakeActorNameBalloon");
void CGameMode::MakeActorNameBalloon(CGameActor* theActor) // line 2362
{
	return (this->*_MakeActorNameBalloon)(theActor);

	this->CGameMode::MakeNameBalloonTextWindow((UIWindow**)&m_nameBalloon);

	bool cutSharp = ( theActor->CGameActor::GetJob() < 45 || theActor->CGameActor::GetJob() > 4000 );
	const NamePair& np = this->CGameMode::GetActorName(theActor->CGameActor::GetGID());
	m_nameBalloon->SetNameText(np, cutSharp);

	char emblemResName[256];
	const char* pemblemResName;

	if( theActor->GetGdid() && g_session.m_emblemState )
	{
		g_session.CSession::GetEmblemFileName(emblemResName, theActor->GetGdid(), theActor->GetEmblemVersion());
		pemblemResName = emblemResName;
	}
	else
	{
		pemblemResName = "";
	}

	m_nameBalloon->SetEmblemResName(pemblemResName);
	m_nameBalloonWidth = m_nameBalloon->UIWindow::GetWidth();
	m_nameBalloonHeight = m_nameBalloon->UIWindow::GetHeight();

	int job = theActor->CGameActor::GetJob();
	unsigned long color;

	if( IsNameYellow(theActor->CGameActor::GetGID()) )
		color = 0x0000FFFF;
	else
	if( job > 45 && job < 1000 )
		color = 0x00F7B895;
	else
	if( job > 1000 && job < 4000 )
		color = 0x00C3C3FF;
	else
		color = 0x00FFFFFF;

	m_nameBalloon->UIBalloonText::SetFntColor(color, 0);
	this->CGameMode::MoveBalloonTextWindow(m_nameBalloon, theActor);
}


hook_method<void (CGameMode::*)(void)> CGameMode::_ProcessNameBalloon(SAKEXE, "CGameMode::ProcessNameBalloon");
void CGameMode::ProcessNameBalloon(void) // line 2412-2525
{
	return (this->*_ProcessNameBalloon)();

	//TODO
}


hook_method<CGameActor* (CGameMode::*)(int job)> CGameMode::_NewNpc(SAKEXE, "CGameMode::NewNpc");
CGameActor* CGameMode::NewNpc(int job) // line 3895
{
	return (this->*_NewNpc)(job);

	const char* jobName = g_session.CSession::GetJobName(job);

	if( strstr(jobName, ".gr2") != NULL )
		return new C3dGrannyGameActor(const_cast<char*>(jobName));
	else
		return new CNpc();
}


hook_method<void (CGameMode::*)(vector3d* pos, int effectId, int lastTime, int F1)> CGameMode::_PlaceEffect(SAKEXE, "CGameMode::PlaceEffect");
void CGameMode::PlaceEffect(vector3d* pos, int effectId, int lastTime, int F1)
{
	return (this->*_PlaceEffect)(pos, effectId, lastTime, F1);

	//TODO
}


hook_method<void (CGameMode::*)(vector3d& sPos, unsigned long targetGid, float hideTime, int job)> CGameMode::_MakeArrowEffect(SAKEXE, "CGameMode::MakeArrowEffect");
void CGameMode::MakeArrowEffect(vector3d& sPos, unsigned long targetGid, float hideTime, int job) // line 1549
{
	return (this->*_MakeArrowEffect)(sPos, targetGid, hideTime, job);

	//TODO
}


hook_method<void (CGameMode::*)(unsigned long targetGid, int job, float hideTime)> CGameMode::_MakeMandraAttackEffect(SAKEXE, "CGameMode::MakeMandraAttackEffect");
void CGameMode::MakeMandraAttackEffect(unsigned long targetGid, int job, float hideTime) // line 1565
{
	return (this->*_MakeMandraAttackEffect)(targetGid, job, hideTime);

	//TODO
}


hook_method<void (CGameMode::*)(float cx, float cy, float cz, const char* actName, const char* sprName, int action, int motion, float roty)> CGameMode::_MakeCorpse(SAKEXE, "CGameMode::MakeCorpse");
void CGameMode::MakeCorpse(float cx, float cy, float cz, const char* actName, const char* sprName, int action, int motion, float roty)
{
	return (this->*_MakeCorpse)(cx, cy, cz, actName, sprName, action, motion, roty);

	//TODO
}


hook_method<void (CGameMode::*)(float cx, float cy, float cz, float fRot, const char* Gr2Name)> CGameMode::_MakeGrannyCorpse3d(SAKEXE, "CGameMode::MakeGrannyCorpse3d");
void CGameMode::MakeGrannyCorpse3d(float cx, float cy, float cz, float fRot, const char* Gr2Name)
{
	return (this->*_MakeGrannyCorpse3d)(cx, cy, cz, fRot, Gr2Name);

	//TODO
}


hook_method<void (CGameMode::*)(CGameActor* theActor, int gdid, int emblemVer)> CGameMode::_MakeEmblemWnd(SAKEXE, "CGameMode::MakeEmblemWnd");
void CGameMode::MakeEmblemWnd(CGameActor* theActor, int gdid, int emblemVer) // line 5325
{
	return (this->*_MakeEmblemWnd)(theActor, gdid, emblemVer);

	//TODO
}


//hook_method<void (CGameMode::*)(void)> CGameMode::_InvalidatePlayerGage(SAKEXE, "CGameMode::InvalidatePlayerGage");
void CGameMode::InvalidatePlayerGage(void) // line ????
{
//	return (this->*_InvalidatePlayerGage)();

	if( m_playerGage != NULL )
		m_playerGage->Invalidate();
}


hook_method<void (CGameMode::*)(void)> CGameMode::_HideCheck(SAKEXE, "CGameMode::HideCheck");
void CGameMode::HideCheck(void) // line 3199-3246
{
	return (this->*_HideCheck)();

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_DrawMiniMap(SAKEXE, "CGameMode::DrawMiniMap");
void CGameMode::DrawMiniMap(void) // line 1175
{
	return (this->*_DrawMiniMap)();

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_DrawPKRanking(SAKEXE, "CGameMode::DrawPKRanking");
void CGameMode::DrawPKRanking(void) // line 908
{
	return (this->*_DrawPKRanking)();

	//TODO
}


hook_method<void (CGameMode::*)(unsigned long timeTick, int showType)> CGameMode::_DrawTime(SAKEXE, "CGameMode::DrawTime");
void CGameMode::DrawTime(unsigned long timeTick, int showType) // line 1007
{
	return (this->*_DrawTime)(timeTick, showType);

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_DrawDragImage(SAKEXE, "CGameMode::DrawDragImage");
void CGameMode::DrawDragImage(void) // line 1154
{
	return (this->*_DrawDragImage)();

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_DrawIllustImage(SAKEXE, "CGameMode::DrawIllustImage");
void CGameMode::DrawIllustImage(void) // line 848
{
	return (this->*_DrawIllustImage)();

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_DrawUseSkillLevelNumber(SAKEXE, "CGameMode::DrawUseSkillLevelNumber");
void CGameMode::DrawUseSkillLevelNumber(void) // line 791
{
	return (this->*_DrawUseSkillLevelNumber)();

	//TODO
}


hook_method<const char* (CGameMode::*)(void)> CGameMode::_GetDragItemName(SAKEXE, "CGameMode::GetDragItemName");
const char* CGameMode::GetDragItemName(void) // line 3931
{
	return (this->*_GetDragItemName)();

	//TODO
}


//hook_method<DRAG_INFO* (CGameMode::*)(void)> CGameMode::_GetDragInfo(SAKEXE, "CGameMode::GetDragInfo");
DRAG_INFO* CGameMode::GetDragInfo(void) // line ????
{
//	return (this->*_GetDragInfo)();

	return &m_dragInfo;
}


ENUM_DRAGTYPE CGameMode::GetDragType()
{
	return m_dragInfo.m_dragType;
}


int CGameMode::GetNumDragItem()
{
	return m_dragInfo.m_numDragItem;
}


int CGameMode::GetDragItemIndex()
{
	return m_dragInfo.m_dragItemIndex;
}


//hook_method<int (CGameMode::*)(void)> CGameMode::_CanRotateView(SAKEXE, "CGameMode::CanRotateView");
int CGameMode::CanRotateView(void) // line ????
{
//	return (this->*_CanRotateView)();

	return m_canRotateView;
}


hook_method<void (CGameMode::*)(int val1, int val2)> CGameMode::_ProcessTalkType(SAKEXE, "CGameMode::ProcessTalkType");
void CGameMode::ProcessTalkType(int val1, int val2) // line 4129
{
	return (this->*_ProcessTalkType)(val1, val2);

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_ProcessLockOnMouse(SAKEXE, "CGameMode::ProcessLockOnMouse");
void CGameMode::ProcessLockOnMouse(void) // line 3138-3196
{
	return (this->*_ProcessLockOnMouse)();

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_ProcessAssignAID(SAKEXE, "CGameMode::ProcessAssignAID");
void CGameMode::ProcessAssignAID(void) // line 5559
{
	return (this->*_ProcessAssignAID)();

	//TODO
}


hook_method<int (CGameMode::*)(int processType, CActorPickInfo* actorInfo)> CGameMode::_ProcessActorPick(SAKEXE, "CGameMode::ProcessActorPick");
int CGameMode::ProcessActorPick(int processType, CActorPickInfo* actorInfo) // line 2702
{
	return (this->*_ProcessActorPick)(processType, actorInfo);

	//TODO
}


hook_method<void (CGameMode::*)(int& processType, CActorPickInfo* actorInfo, CGameActor* pc)> CGameMode::_ProcessPcPick(SAKEXE, "CGameMode::ProcessPcPick");
void CGameMode::ProcessPcPick(int& processType, CActorPickInfo* actorInfo, CGameActor* pc) // line 2555
{
	return (this->*_ProcessPcPick)(processType, actorInfo, pc);

	//TODO
}


hook_method<void (CGameMode::*)(int& processType, CActorPickInfo* actorInfo, CGameActor* monster)> CGameMode::_ProcessMonsterPick(SAKEXE, "CGameMode::ProcessMonsterPick");
void CGameMode::ProcessMonsterPick(int& processType, CActorPickInfo* actorInfo, CGameActor* monster) // line 2637
{
	return (this->*_ProcessMonsterPick)(processType, actorInfo, monster);

	int keystate = (GetAsyncKeyState(16) >> 8) & 0xFF;
	bool attackCanBeApplied = ( keystate == 0 );

	if( m_skillUseInfo.m_skillUseType == 2 || m_skillUseInfo.m_skillUseType == 4 )
	{
		bool isGoodSkill = SKILL_INFO::IsGoodSkillForActor(m_skillUseInfo.m_skillId);
		if( isGoodSkill )
			attackCanBeApplied = ( keystate != 0 );
		
		this->CMode::SetCursorAction(11);
	}
	else
	if( monster->CGameActor::GetHeadType() == 20 )
	{
		this->CMode::SetCursorAction(0);
	}
	else
	if( !m_world->CWorld::IsSiegeMode() )
	{
		this->CMode::SetCursorAction(5);
	}
	else
	if( g_session.CSession::IsMyGuild(monster->GetGdid()) )
	{
		attackCanBeApplied = false;
		this->CMode::SetCursorAction(0);
	}

	processType = 1;

	if( g_session.m_isNoShift == 1 )
		attackCanBeApplied = true;

	if( g_mouse.CMouse::GetLBtn() == 1 && attackCanBeApplied )
	{
		this->SendMsg(28, 1, 0, 0);
		m_lastLockOnMonGid = m_lastMonGid;
		m_isAutoMoveClickOn = 0;

		if( (!g_session.CSession::IsSiegeMode() && GetAsyncKeyState(17) >> 8 != 0) || g_session.m_isNoCtrl )
		{
			if( m_skillUseInfo.m_skillId == 10000 || !this->CGameMode::AttackSkillOverWeightMessage() )
			{
				if( m_skillUseInfo.m_skillUseType == 0 )
				{
					m_world->m_player->SendMsg(NULL, 10, m_lastMonGid, 0, 0);
				}
				else
				if( m_skillUseInfo.m_skillUseType == 2 || m_skillUseInfo.m_skillUseType == 4 )
				{
					m_world->m_player->SendMsg(NULL, 41, m_lastMonGid, m_skillUseInfo.m_skillId, m_skillUseInfo.m_attackRange);
					m_world->m_player->SendMsg(NULL, 90, m_skillUseInfo.m_useLevel, 0, 0);
				}
			}

			m_isCtrlLock = 1;
		}
		else
		{
			if( m_skillUseInfo.m_skillId == 10000 || !this->CGameMode::AttackSkillOverWeightMessage() )
			{
				if( m_skillUseInfo.m_skillUseType == 0 )
				{
					m_world->m_player->SendMsg(NULL, 10, m_lastMonGid, 1, 0);
				}
				else
				if( m_skillUseInfo.m_skillUseType == 2 || m_skillUseInfo.m_skillUseType == 4 )
				{
					m_world->m_player->SendMsg(NULL, 41, m_lastMonGid, m_skillUseInfo.m_skillId, m_skillUseInfo.m_attackRange);
					m_world->m_player->SendMsg(NULL, 90, m_skillUseInfo.m_useLevel, 0, 0);
				}
			}

			m_isCtrlLock = 0;
		}
	}
	else
	{
		if( !m_isCtrlLock && g_mouse.CMouse::GetLBtn() == 3 )
			m_lastMonGid = 0;
	}

	if( m_oldMouseX != g_mouse.CMouse::GetXPos() || m_oldMouseY != g_mouse.CMouse::GetYPos() )
	{
		if( !m_isCtrlLock && g_mouse.CMouse::GetLBtn() == 0 )
			m_lastMonGid = 0;
	}

	this->CGameMode::MakeNameBalloon(m_lastMonGid);

	if( monster->m_stateId == STATEID_DEAD )
		m_lastMonGid = 0;
}


hook_method<void (CGameMode::*)(void)> CGameMode::_WriteNameBalloonPosToReg(SAKEXE, "CGameMode::WriteNameBalloonPosToReg");
void CGameMode::WriteNameBalloonPosToReg(void) // line 374-395
{
	return (this->*_WriteNameBalloonPosToReg)();

	char SubKey[256];
	strcpy(SubKey, g_regPath);
	strcat(SubKey, "\\NameBaloon");
	strcat(SubKey, "\\");
	strcat(SubKey, g_session.m_lastServerName.c_str());

	HKEY hKey;
	DWORD dwDisposition = 0;
	if( RegCreateKeyExA(HKEY_LOCAL_MACHINE, (LPCSTR)&SubKey, 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, &dwDisposition) != ERROR_SUCCESS )
		return; // failure
	RegSetValueExA(hKey, "POS", 0, 4u, (BYTE*)&m_nameBalloonType, 4u);
	RegCloseKey(hKey);
}


hook_method<void (CGameMode::*)(void)> CGameMode::_InitNameBalloonPosFromReg(SAKEXE, "CGameMode::InitNameBalloonPosFromReg");
void CGameMode::InitNameBalloonPosFromReg(void) // line 398-430
{
	return (this->*_InitNameBalloonPosFromReg)();

	char NameBalloonPosPath[512];
	strcpy(NameBalloonPosPath, g_regPath);
	strcat(NameBalloonPosPath, "\\NameBaloon");
	strcat(NameBalloonPosPath, "\\");
	strcat(NameBalloonPosPath, g_session.m_lastServerName.c_str());

	HKEY hResultKey;
	if( !RegOpenKeyExA(HKEY_LOCAL_MACHINE, NameBalloonPosPath, 0, KEY_QUERY_VALUE, &hResultKey) )
	{
		RegCloseKey(hResultKey);

		HKEY hKey;
		if( !RegOpenKeyExA(HKEY_LOCAL_MACHINE, NameBalloonPosPath, 0, KEY_ALL_ACCESS, &hKey) )
		{
			int REG_TYPE = 4;
			int DATALENGTH = 4;
			RegQueryValueExA(hKey, "POS", 0, (LPDWORD)&REG_TYPE, (LPBYTE)&m_nameBalloonType, (LPDWORD)&DATALENGTH);
			RegCloseKey(hKey);
		}
	}

	if( m_nameBalloonType != 0 && m_nameBalloonType != 1 )
		m_nameBalloonType = 0;
}


hook_method<void (CGameMode::*)(unsigned long itemNaid)> CGameMode::_RemovePickupItemNaid(SAKEXE, "CGameMode::RemovePickupItemNaid");
void CGameMode::RemovePickupItemNaid(unsigned long itemNaid) // line 1968
{
	return (this->*_RemovePickupItemNaid)(itemNaid);

	//TODO
}


hook_method<bool (CGameMode::*)(unsigned long itemNaid)> CGameMode::_IsReqPickupItemNaid(SAKEXE, "CGameMode::IsReqPickupItemNaid");
bool CGameMode::IsReqPickupItemNaid(unsigned long itemNaid)
{
	return (this->*_IsReqPickupItemNaid)(itemNaid);

	//TODO
}


hook_method<void (CGameMode::*)(unsigned long itemNaid)> CGameMode::_AddPickupItemNaid(SAKEXE, "CGameMode::AddPickupItemNaid");
void CGameMode::AddPickupItemNaid(unsigned long itemNaid)
{
	return (this->*_AddPickupItemNaid)(itemNaid);

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_ProcessPlayWave(SAKEXE, "CGameMode::ProcessPlayWave");
void CGameMode::ProcessPlayWave(void) // line 5469
{
	return (this->*_ProcessPlayWave)();

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_ResetDrag(SAKEXE, "CGameMode::ResetDrag");
void CGameMode::ResetDrag(void) // line 774-788
{
	return (this->*_ResetDrag)();

	m_dragInfo.m_isIdentified = 0;
	m_dragInfo.m_dragItemIndex = 0;
	m_dragInfo.m_dragItemName = "";
	m_dragInfo.m_dragItemPrice = 0;
	m_dragInfo.m_dragSprName = "";
	m_dragInfo.m_slotNum = -1;
	m_dragInfo.m_dragType = DT_NODRAG;
	m_dragInfo.m_numDragItem = 0;
	m_dragInfo.m_skillUseLevel = 0;
	m_dragInfo.m_refiningLevel = 0;
	m_dragInfo.m_slot[0] = 0;
	m_dragInfo.m_slot[1] = 0;
	m_dragInfo.m_slot[2] = 0;
	m_dragInfo.m_slot[3] = 0;
}


//hook_method<void (CGameMode::*)(int wait)> CGameMode::_SetWaitUseItemAck(SAKEXE, "CGameMode::SetWaitUseItemAck");
void CGameMode::SetWaitUseItemAck(int wait)
{
//	return (this->*_SetWaitUseItemAck)(wait);

	m_waitingUseItemAck = wait;
}


hook_method<void (CGameMode::*)(char* txt)> CGameMode::_WriteChat(SAKEXE, "CGameMode::WriteChat");
void CGameMode::WriteChat(char* txt) // line 5496
{
	return (this->*_WriteChat)(txt);

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_CloseChatFile(SAKEXE, "CGameMode::CloseChatFile");
void CGameMode::CloseChatFile(void) // line 5537-5545
{
	return (this->*_CloseChatFile)();

	if( g_session.m_isSaveChat && g_session.CSession::IsMasterAid(7) )
	{
		char tmp2[256];
		char tmp[256];
		sprintf(tmp, "%s", saveChatFp.CFile::GetFileName());
		sprintf(tmp2, "%s.bak", tmp);
		saveChatFp.CFile::Close();
	}
}


hook_method<void (CGameMode::*)(int state)> CGameMode::_OnChangeState(SAKEXE, "CGameMode::OnChangeState");
void CGameMode::OnChangeState(int state) // line 3876
{
	return (this->*_OnChangeState)(state);

	;
}


hook_method<void (CGameMode::*)(int id)> CGameMode::_DeleteCompassPos(SAKEXE, "CGameMode::DeleteCompassPos");
void CGameMode::DeleteCompassPos(int id) // line 3970
{
	return (this->*_DeleteCompassPos)(id);

	//TODO
}


hook_method<void (CGameMode::*)(UIWindow** window)> CGameMode::_MakeNameBalloonTextWindow(SAKEXE, "CGameMode::MakeNameBalloonTextWindow");
void CGameMode::MakeNameBalloonTextWindow(UIWindow** window) // line 3999
{
	return (this->*_MakeNameBalloonTextWindow)(window);

	//TODO
}


hook_method<void (CGameMode::*)(UIWindow* window, CRenderObject* renderObject)> CGameMode::_MoveBalloonTextWindow(SAKEXE, "CGameMode::MoveBalloonTextWindow");
void CGameMode::MoveBalloonTextWindow(UIWindow* window, CRenderObject* renderObject) // line 4048
{
	return (this->*_MoveBalloonTextWindow)(window, renderObject);

	//TODO
}


hook_method<void (CGameMode::*)(void)> CGameMode::_ProcessAutoFollow(SAKEXE, "CGameMode::ProcessAutoFollow");
void CGameMode::ProcessAutoFollow(void) // line 5276-5322
{
	return (this->*_ProcessAutoFollow)();

	if( CGameMode::m_lastLockOnPcGid == 0 )
		return;

	if( g_mouse.CMouse::GetLBtn() != BTN_NONE )
	{
		CGameMode::m_lastLockOnPcGid = 0;
		CGameMode::m_dwOldDisappearTime = 0;
		CGameMode::m_dwOldAutoFollowTime = 0;
		return;
	}

	CGameActor* actor = m_world->CWorld::GetGameActorByAID(CGameMode::m_lastLockOnPcGid);
	if( actor == NULL )
	{
		if( CGameMode::m_dwOldDisappearTime == 0 )
			CGameMode::m_dwOldDisappearTime = timeGetTime();

		if( timeGetTime() - CGameMode::m_dwOldDisappearTime > 10000 )
		{
			CGameMode::m_lastLockOnPcGid = 0;
			CGameMode::m_dwOldAutoFollowTime = 0;
			CGameMode::m_dwOldDisappearTime = 0;
		}

		return;
	}

	CGameMode::m_dwOldDisappearTime = 0;

	if( timeGetTime() - CGameMode::m_dwOldAutoFollowTime <= 1000 )
		return;

	CGameMode::m_dwOldAutoFollowTime = timeGetTime();

	int dx = actor->m_moveDestX;
	int dy = actor->m_moveDestY;

	if( g_windowMgr.UIWindowMgr::GetChatRoomWnd() != NULL || m_world->m_player->m_stateId == STATEID_SIT )
	{
		m_world->m_player->SendMsg(NULL, 16, dx, dy, 0);
		return;
	}

	if( !this->CGameMode::IsValidCell(dx, dy) && !this->CGameMode::GetClosestValidCell(dx, dy) )
			return;

	if( g_windowMgr.UIWindowMgr::GetMenu() != NULL )
		g_windowMgr.UIWindowMgr::DeleteWindow(WID_MENUWND);

	m_world->m_player->SendMsg(NULL, 17, dx, dy, 0);
}


class hook_ptr<struct mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,struct NamePair>,struct mystd::map<unsigned long,struct NamePair,struct mystd::less<unsigned long>,class mystd::allocator<struct NamePair> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<struct NamePair> >::_Node *> mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,struct NamePair>,struct mystd::map<unsigned long,struct NamePair,struct mystd::less<unsigned long>,class mystd::allocator<struct NamePair> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<struct NamePair> >::_Nil(SAKEXE, "?_Nil@?$_Tree@KU?$pair@$$CBKUNamePair@@@std@@U_Kfn@?$map@KUNamePair@@U?$less@K@std@@V?$allocator@UNamePair@@@3@@2@U?$less@K@2@V?$allocator@UNamePair@@@2@@std@@1PAU_Node@12@A");
class hook_val<unsigned int> mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,struct NamePair>,struct mystd::map<unsigned long,struct NamePair,struct mystd::less<unsigned long>,class mystd::allocator<struct NamePair> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<struct NamePair> >::_Nilrefs(SAKEXE, "?_Nilrefs@?$_Tree@KU?$pair@$$CBKUNamePair@@@std@@U_Kfn@?$map@KUNamePair@@U?$less@K@std@@V?$allocator@UNamePair@@@3@@2@U?$less@K@2@V?$allocator@UNamePair@@@2@@std@@1IA");
class hook_ptr<struct mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,unsigned long>,struct mystd::map<unsigned long,unsigned long,struct mystd::less<unsigned long>,class mystd::allocator<unsigned long> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<unsigned long> >::_Node *> mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,unsigned long>,struct mystd::map<unsigned long,unsigned long,struct mystd::less<unsigned long>,class mystd::allocator<unsigned long> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<unsigned long> >::_Nil(SAKEXE, "?_Nil@?$_Tree@KU?$pair@$$CBKK@std@@U_Kfn@?$map@KKU?$less@K@std@@V?$allocator@K@2@@2@U?$less@K@2@V?$allocator@K@2@@std@@1PAU_Node@12@A");
class hook_val<unsigned int> mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,unsigned long>,struct mystd::map<unsigned long,unsigned long,struct mystd::less<unsigned long>,class mystd::allocator<unsigned long> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<unsigned long> >::_Nilrefs(SAKEXE, "?_Nilrefs@?$_Tree@KU?$pair@$$CBKK@std@@U_Kfn@?$map@KKU?$less@K@std@@V?$allocator@K@2@@2@U?$less@K@2@V?$allocator@K@2@@std@@1IA");
class hook_ptr<struct mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,int>,struct mystd::map<unsigned long,int,struct mystd::less<unsigned long>,class mystd::allocator<int> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<int> >::_Node *> mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,int>,struct mystd::map<unsigned long,int,struct mystd::less<unsigned long>,class mystd::allocator<int> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<int> >::_Nil(SAKEXE, "?_Nil@?$_Tree@KU?$pair@$$CBKH@std@@U_Kfn@?$map@KHU?$less@K@std@@V?$allocator@H@2@@2@U?$less@K@2@V?$allocator@H@2@@std@@1PAU_Node@12@A");
class hook_val<unsigned int> mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,int>,struct mystd::map<unsigned long,int,struct mystd::less<unsigned long>,class mystd::allocator<int> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<int> >::_Nilrefs(SAKEXE, "?_Nilrefs@?$_Tree@KU?$pair@$$CBKH@std@@U_Kfn@?$map@KHU?$less@K@std@@V?$allocator@H@2@@2@U?$less@K@2@V?$allocator@H@2@@std@@1IA");
class hook_ptr<struct mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,struct CellPos>,struct mystd::map<unsigned long,struct CellPos,struct mystd::less<unsigned long>,class mystd::allocator<struct CellPos> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<struct CellPos> >::_Node *> mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,struct CellPos>,struct mystd::map<unsigned long,struct CellPos,struct mystd::less<unsigned long>,class mystd::allocator<struct CellPos> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<struct CellPos> >::_Nil(SAKEXE, "?_Nil@?$_Tree@KU?$pair@$$CBKUCellPos@@@std@@U_Kfn@?$map@KUCellPos@@U?$less@K@std@@V?$allocator@UCellPos@@@3@@2@U?$less@K@2@V?$allocator@UCellPos@@@2@@std@@1PAU_Node@12@A");
class hook_val<unsigned int> mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,struct CellPos>,struct mystd::map<unsigned long,struct CellPos,struct mystd::less<unsigned long>,class mystd::allocator<struct CellPos> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<struct CellPos> >::_Nilrefs(SAKEXE, "?_Nilrefs@?$_Tree@KU?$pair@$$CBKUCellPos@@@std@@U_Kfn@?$map@KUCellPos@@U?$less@K@std@@V?$allocator@UCellPos@@@3@@2@U?$less@K@2@V?$allocator@UCellPos@@@2@@std@@1IA");
class hook_ptr<struct mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,struct ColorCellPos>,struct mystd::map<unsigned long,struct ColorCellPos,struct mystd::less<unsigned long>,class mystd::allocator<struct ColorCellPos> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<struct ColorCellPos> >::_Node *> mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,struct ColorCellPos>,struct mystd::map<unsigned long,struct ColorCellPos,struct mystd::less<unsigned long>,class mystd::allocator<struct ColorCellPos> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<struct ColorCellPos> >::_Nil(SAKEXE, "?_Nil@?$_Tree@KU?$pair@$$CBKUColorCellPos@@@std@@U_Kfn@?$map@KUColorCellPos@@U?$less@K@std@@V?$allocator@UColorCellPos@@@3@@2@U?$less@K@2@V?$allocator@UColorCellPos@@@2@@std@@1PAU_Node@12@A");
class hook_val<unsigned int> mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,struct ColorCellPos>,struct mystd::map<unsigned long,struct ColorCellPos,struct mystd::less<unsigned long>,class mystd::allocator<struct ColorCellPos> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<struct ColorCellPos> >::_Nilrefs(SAKEXE, "?_Nilrefs@?$_Tree@KU?$pair@$$CBKUColorCellPos@@@std@@U_Kfn@?$map@KUColorCellPos@@U?$less@K@std@@V?$allocator@UColorCellPos@@@3@@2@U?$less@K@2@V?$allocator@UColorCellPos@@@2@@std@@1IA");
class hook_ptr<struct mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,struct ColorCellPos2>,struct mystd::map<unsigned long,struct ColorCellPos2,struct mystd::less<unsigned long>,class mystd::allocator<struct ColorCellPos2> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<struct ColorCellPos2> >::_Node *> mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,struct ColorCellPos2>,struct mystd::map<unsigned long,struct ColorCellPos2,struct mystd::less<unsigned long>,class mystd::allocator<struct ColorCellPos2> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<struct ColorCellPos2> >::_Nil(SAKEXE, "?_Nil@?$_Tree@KU?$pair@$$CBKUColorCellPos2@@@std@@U_Kfn@?$map@KUColorCellPos2@@U?$less@K@std@@V?$allocator@UColorCellPos2@@@3@@2@U?$less@K@2@V?$allocator@UColorCellPos2@@@2@@std@@1PAU_Node@12@A");
class hook_val<unsigned int> mystd::_Tree<unsigned long,struct mystd::pair<unsigned long const ,struct ColorCellPos2>,struct mystd::map<unsigned long,struct ColorCellPos2,struct mystd::less<unsigned long>,class mystd::allocator<struct ColorCellPos2> >::_Kfn,struct mystd::less<unsigned long>,class mystd::allocator<struct ColorCellPos2> >::_Nilrefs(SAKEXE, "?_Nilrefs@?$_Tree@KU?$pair@$$CBKUColorCellPos2@@@std@@U_Kfn@?$map@KUColorCellPos2@@U?$less@K@std@@V?$allocator@UColorCellPos2@@@3@@2@U?$less@K@2@V?$allocator@UColorCellPos2@@@2@@std@@1IA");
